zoukankan      html  css  js  c++  java
  • 线程间的通信

    在一个进程中,线程往往不是孤立存在的,多个线程之间要经常进行通信,成为线程间的通信。

    线程间的通信主要体现在,一个线程执行完特定任务后,转到另一个线程去执行任务,在转换任务的同时,将数据也传递给另外一个线程。

    NSThread类提供了两个比较常用的方法,用于实现线程间的通信,这两个方法的定义格式如下:

    -(void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
    -(void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
    在上述定义的格式中,第一个方法是将指定的方法放在主线程中运行。其中,aSelector就是在主线程中运行的方法,参数arg是当前执行方法所在的线程传递给主线程的参数,参数waitUntilDone是一个布尔值,用来指定当前线程是否阻塞,当为YES的时候会阻塞当前线程,直到主线程执行完毕后才执行当前线程;当为NO的时候,则不阻塞这个线程。
    第二个方法是创建一个子线程,将指定的方法放在子线程中运行。

    下面通过一个使用多线程下载网络图片的案例,展示如何实现线程间的通信:

    1、新建一个Single View Application 应用,名称为03-ThreadContact;

    2、进入Main.StoryBoard,从对象库拖拽一个ImageView到程序界面,用于显示要下载的图片,设置Mode模式为Center,最后给Image View设置一个背景颜色;

    3、通过拖拽的方式,将ImageView在viewController.m文件的类扩展中进行属性的声明;

    4、单击模拟器的屏幕,开始下载图片,并将下载完成的图片显示到ImageView上。

    注意:程序如果直接在主线程中访问网络数据,由于网络速度的不稳定性,一旦网络传输速度较慢时,容易造成主线程的阻塞,从而导致应用程序失去响应。因此需要将网络下载图片这样耗时的操作放到子线程中,等下载完成后,通知主线程刷新视图,显示图片。

    整个程序的代码如下:

    #import "ViewController.h"

    @interface ViewController ()
    @property (weak, nonatomic) IBOutlet UIImageView *HM;

    @end

    @implementation ViewController
    // 单击屏幕
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
    [self performSelectorInBackground:@selector(download) withObject:nil];
    }
    //下载图片
    -(void)download
    {
    NSLog(@"download---%@",[NSThread currentThread]);
    //1.图片地址
    NSString *urlStr=@"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1206121028,2489642848&fm=27&gp=0.jpg";
    NSURL *url=[NSURL URLWithString:urlStr];
    // 2.根据地址下载图片的二进制数据(这句代码最耗时)
    NSData *data=[NSData dataWithContentsOfURL:url];
    //3.设置图片
    UIImage *image=[UIImage imageWithData:data];
    //4.回到主线程,刷新UI界面(为了线程安全)
    if(image!=nil)
    {
    [self performSelectorOnMainThread:@selector(downloadFinished:) withObject:image waitUntilDone:NO];
    }
    else
    {
    NSLog(@"图片下载出现错误!");
    }
    }
    //下载完成
    -(void)downloadFinished:(UIImage *)image
    {
    self.HM.image=image;
    NSLog(@"downloadFinished---%@",[NSThread currentThread]);
    }

    - (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    }
    - (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
    }

    @end
    代码中,performSelectorInBackground: withObject:方法创建子线程,并指定了download方法来下载图片,后面调用

    performSelectorOnMainThread: withObject: waitUntilDone:来到主线程,在主线程中刷新视图。

    运行程序,程序运行成功后,单击屏幕,就成功下载了图片,模拟器的结果如下:
         

    控制台输出结果如下:


    ---------------------
    作者:ChunxueShi
    来源:CSDN
    原文:https://blog.csdn.net/shichunxue/article/details/78481428
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    POJ1094(Topological Sort)
    POJ1258(Minimum Spanning Tree,Prim)
    POJ2509(Water,Greedy)
    POJ1258(Minimum Spanning Tree,Kruskal)
    POJ1256(permutation)
    POJ2790(BFS)
    HDU 1527 取石子游戏
    POJ Mayor's posters
    HDU 1907 John
    HDU 2516 取石子游戏
  • 原文地址:https://www.cnblogs.com/striveLD/p/9930032.html
Copyright © 2011-2022 走看看