1、什么叫做线程间通信
在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信
2、线程间通信的体现
1个线程传递数据给另1个线程
在1个线程中执行完特定任务后,转到另1个线程继续执行任务
3、线程间通信示例
UIImageView下载图片这个例子, 主线程中开启一个子线程去下载图片, 当图片下载完成之后再回到主线程中更新显示图片, 这样的一个过程就是线程间通信的一个过程.
4、NSThread线程间通信常用方法
// 第一种
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
// 第二种 - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
5、使用NSThread多线程间通信
1 - (void)viewDidLoad 2 { 3 [super viewDidLoad]; 4 5 // 使用多线程来下载图片 6 [NSThread detachNewThreadSelector:@selector(downloadImage) toTarget:self withObject:nil]; 7 } 8 9 - (void)downloadImage 10 { 11 NSLog(@"开始下载图片 %@", [NSThread currentThread]); 12 13 // 下载的方法 14 // 1. url网络资源 15 NSURL *url = [NSURL URLWithString:@"http://pic12.nipic.com/20110124/4814485_135921152102_2.jpg"]; 16 17 // 2. OC原生的方法,网络上的所有数据都是以“二进制或者字符串”的方式传递的 18 // 在以后的开发中,几乎不用,因为性能太差 19 NSData *data = [NSData dataWithContentsOfURL:url]; 20 21 // 3. 根据下载的数据建立图像 22 UIImage *image = [UIImage imageWithData:data]; 23 24 NSLog(@"完成下载图片 %@", [NSThread currentThread]); 25 26 // 更新UI,需要在主线程上进行 27 // waitUntilDone:是否等待setImage:方法结束 28 [self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO]; 29 }
以上代码是用NSThread多线程方式实现子线程下载图片,在主线程更新UI的操作
上边这段代码是有问题的,应该在多线程上加一个自动释放池
6、使用GCD完成多线程间通信
1 - (void)viewDidLoad 2 { 3 [super viewDidLoad]; 4 5 // 下载图片 6 [self downloadImage]; 7 } 8 9 - (void)downloadImage 10 { 11 // 1. 全局并行队列 12 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 13 14 // 2. 异步任务 15 dispatch_async(queue, ^{ 16 NSLog(@"开始下载图片 %@", [NSThread currentThread]); 17 18 // 下载的方法 19 // 1. url网络资源 20 NSURL *url = [NSURL URLWithString:@"http://img.pconline.com.cn/images/upload/upc/tx/wallpaper/1208/30/c0/13398570_1346308990114_800x600.jpg"]; 21 22 // 2. OC原生的方法,网络上的所有数据都是以“二进制或者字符串”的方式传递的 23 // 在以后的开发中,几乎不用,因为性能太差 24 NSData *data = [NSData dataWithContentsOfURL:url]; 25 26 // 3. 根据下载的数据建立图像 27 UIImage *image = [UIImage imageWithData:data]; 28 29 NSLog(@"完成下载图片 %@", [NSThread currentThread]); 30 31 // 4. 通知主队列更新UI 32 // 给主队列,添加一个异步任务,更新UI 33 dispatch_async(dispatch_get_main_queue(), ^{ 34 self.image = image; 35 }); 36 }); 37 }
与NSThread方式相比,不用考虑自动释放池的问题,而且异步任务的操作都是放在块代码中,比较集中,可读性好。