网络操作不能直接写在主线程中 以及 为什么不能在子线程中更新UI控件的属性

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //注意: 所有网络操作不能直接写在主线程中 因为所有的网络操作都是耗时的,如果加载到主线程中,会导致与用户的交互出现问题 ,所以要加载到子线程中
//    [self loadImage];
    
   [self performSelectorInBackground:@selector(loadImage) withObject:nil];

}

//加载网络图片
- (void)loadImage{
    //所有网络上的东西都是有地址的. 要获取网络数据,必须要知道这个网络数据的地址.
    NSURL *url = [NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/pic/item/d788d43f8794a4c274c8110d0bf41bd5ad6e3928.jpg"];
    
    NSData *data = [NSData dataWithContentsOfURL:url];
    self.imageData = data;
    NSLog(@"%@",[NSThread currentThread]);
    //在子线程中直接更新UI会报错, 千万不能在子线程中更新UI (假如允许任意子线程访问、修改UI控件的属性,这就需要对多个新线程的并发访问进行同步控制,否则多个线程将会破坏UI控件内部状态的完整性)
//    self.imageView.image = [UIImage imageWithData:data];
    
//    解决方法(网络操作必须在子线程中,网络操作完成后,而更新UI操作又不能在子线程中,这里用到线程间的通信)
    //waitUntilDone : 这个参数表示是否等方法执行完成之后, 才去执行后面的代码, 一般我们写NO
    [self performSelectorOnMainThread:@selector(updateImageView) withObject:nil waitUntilDone:NO];
    
    
}
     
- (void)updateImageView{
    self.imageView.image = [UIImage imageWithData:self.imageData];
    
}

 

1.所有网络操作不能直接写在主线程中 因为所有的网络操作都是耗时的,如果加载到主线程中,会导致与用户的交互出现问题 ,所以要加载到子线程中

2.在子线程中直接更新UI会报错, 千万不能在子线程中更新UI (假如允许任意子线程访问、修改UI控件的属性,这就需要对多个新线程的并发访问进行同步控制,否则多个线程将会破坏UI控件内部状态的完整性)

3.解决方法(网络操作必须在子线程中,网络操作完成后,而更新UI操作又不能在子线程中,这里用到线程间的通信)

    //waitUntilDone : 这个参数表示是否等方法执行完成之后, 才去执行后面的代码, 一般我们写NO

 

posted @ 2016-07-02 19:56  爱分享爱生活  阅读(1226)  评论(0编辑  收藏  举报