网络操作不能直接写在主线程中 以及 为什么不能在子线程中更新UI控件的属性
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络操作不能直接写在主线程中 以及 为什么不能在子线程中更新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
以上是关于网络操作不能直接写在主线程中 以及 为什么不能在子线程中更新UI控件的属性的主要内容,如果未能解决你的问题,请参考以下文章
关于Handler的理解,子线程不能更新UI的纠正和回调的思考
android.os.NetworkOnMainThreadException 在4.0之后谷歌强制要求连接网络不能在主线程进行访问