多线程 - 05.线程间的基础通信操作

来源:互联网 发布:淘宝女士酒店职业装 编辑:程序博客网 时间:2024/05/31 19:12

1.概述

  • 线程间通信概念:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信
  • 线程间通信的体现
    • 1个线程传递数据给另1个线程
    • 在1个线程中执行完特定任务后,转到另1个线程继续执行任务
  • 线程间通信常用方法
// 回到主线程- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;// 执行指定线程中的任务- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

2.线程间的通信示例

  • 我们一般将耗时的操作放在子线程中,例如从网上下载数据,很大次数的循环操作等等,以免阻塞主线程
  • 这里以从网上下载一张图片显示到UIImageView上为例:
  • 在主线程中直接下载图片
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{    // 记录下载操作前时间    NSDate *begin = [NSDate date];//    CFAbsoluteTime begin = CFAbsoluteTimeGetCurrent();    // 下载图片    NSURL *url = [NSURL URLWithString:@"http://pic.4j4j.cn/upload/pic/20130531/07ed5ea485.jpg"];    // 获取图片的二进制数据    NSData *data = [NSData dataWithContentsOfURL:url];    // 记录下载操作后时间    NSDate *end = [NSDate date];//    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();    // 计算时间差    NSLog(@"%lf",[end timeIntervalSinceDate:begin]);结果:0.307621//    NSLog(@"%lf",end - begin);// 结果:0.302949    // 将数据转换为图片    UIImage *image = [UIImage imageWithData:data];    // 显示图片    self.iv.image = image;}
  • 利用多线程下载图片,这里有一个注意点
  • 子线程中不要更新UI,可能会导致未知的错误
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{    //开启子线程下载图片    [self performSelector:@selector(downloadImage) withObject:nil];}-(void)downloadImage{    // 下载图片    NSURL *url = [NSURL URLWithString:@"http://pic.4j4j.cn/upload/pic/20130531/07ed5ea485.jpg"];    // 获取图片的二进制数据    NSData *data = [NSData dataWithContentsOfURL:url];    // 将数据转换为图片    UIImage *image = [UIImage imageWithData:data];    // 返回主线程更新UI    [self.iv performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];;}
  • 注意:以上代码,在返回主线程时,我这里取了个巧,是直接调用了self.iv的set方法,将image作为参数传递,不需要再写一个方法来更新UI,比较方便,可以简化代码
  • 提供正常思路的代码
/*     waitUntilDone:      YES: 如果传入YES, 那么会等待updateImage方法执行完毕, 才会继续执行后面的代码     NO:  如果传入NO, 那么不会等待updateImage方法执行完毕, 就可以继续之后后面的代码*/// 回到主线程(该方法可以在指定的线程中, 调用指定对象的指定方法)    [self performSelector:@selector(updateImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];// 也可以使用// 更新UI回调方法-(void)updateImage:(UIImage *)image{    self.iv.image = image;}   
0 0
原创粉丝点击