关于多线程三种语句的实现

来源:互联网 发布:集成电路板编程 编辑:程序博客网 时间:2024/05/16 03:38

       之前做的一些作业Demo都是单线程的。

       今天学了多线程,讲了三种多线程语句。以从网上加载到客户端一张图片为例子。线程的部分相对好理解,毕竟很容易知道讲的是什么,

       多线程,举个例子就是在加载图片的同时,又可以做别的操作

       单线程的话,是无法做别的操作的,在加载图片的时候网速好可能看不出来,因为响应的快的话,几乎瞬间加载成功,又可以做别的操作了。要是下载的话,因为是单线程,下载这个功能独占线程,无法进行其他操作。这个时候引入多线程,将下载这个线程独立出来,与其他操作并行。

    

将要实现这样一个效果,点击加载的时候,测试滑动条是否能滑动

        一、先看单线程的示例代码:

#pragma mark -主线程里面直接请求数据-(void)loadImageInMainThread{    NSURL *url = [NSURL URLWithString:KImageUrl];    NSData *data = [[NSData alloc] initWithContentsOfURL:url];    UIImage *img = [[UIImage alloc] initWithData:data];        [NSThread sleepForTimeInterval:5];//...@4    self.imageView.image = img;}
       其中前三句是比较常用的从网络上加载图片的语句,@4这句是模拟下载过程的,其意思是,这个函数的线程睡眠5秒。而且这一句的作用也很大。

       因为是单线程所以这一句线程睡眠就把整个线程给弄睡眠了。测试结果:睡眠(加载)过程中,是无法拖动滑动条的。

       二、主要的三种多线程代码:

         1、使用block(NSBlockOperation)

#pragma mark - 在新的线程中使用请求图片资源,使用block(NSBlockOperation)-(void)loadImageUseBlockThread{    NSBlockOperation *newThread = [NSBlockOperation blockOperationWithBlock:^{        NSURL *url = [NSURL URLWithString:KImageUrl];        [NSThread sleepForTimeInterval:5];        NSData *data = [[NSData alloc] initWithContentsOfURL:url];        UIImage *img = [[UIImage alloc] initWithData:data];                [self performSelectorOnMainThread:@selector(updateUI:) withObject:img waitUntilDone:YES];    }];    //把新建立的线程加入到queue里面    NSOperationQueue *queue = [[NSOperationQueue alloc]init];    [queue addOperation:newThread];}-(void)updateUI:(UIImage*)img{    self.imageView.image = img;}
        这个方式的特性在于,声明一个线程,然后把线程加入到queue(操作队列里面)。

        其中,声明线程是以NSBlockOperation声明的,它继承自NSOperation,并且根本上可以看做附带一个block的函数。

        block函数中包括加载图片的过程、声明UIImage对象的过程、此类调用装载更新UI函数的线程。

        其中更新UI的函数单独封装。

        2、使用 NSInvocationOperation

#pragma mark - 在新的线程中使用请求图片资源,使用 NSInvocationOperation-(void)loadImageUseInvocationThread{    //创建一个新线程,并分配任务    NSInvocationOperation *invocationThread = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadImage:) object:KImageUrl];    //创建队列    NSOperationQueue *queue = [[NSOperationQueue alloc]init];    [queue addOperation:invocationThread];}-(void)loadImage:(NSString *)urlPath{    //请求图片    NSURL *url = [NSURL URLWithString:urlPath];    [NSThread sleepForTimeInterval:2];    NSData *data = [[NSData alloc] initWithContentsOfURL:url];    UIImage *img = [[UIImage alloc] initWithData:data];    //主线程去更新UI    [self performSelectorOnMainThread:@selector(updateUI:) withObject:img waitUntilDone:YES];}<pre name="code" class="html">-(void)updateUI:(UIImage*)img{    self.imageView.image = img;}


        这种方式中,直接声明创建一个线程,然后把线程加入到queue

        这里的创建线程只是一个运用 NSInvocationOperation声明初始化的语句。其中装载图片加载图片更新UI单独封装成一个函数作为初始化的选择所选函数。

        3、使用GCD

#pragma mark - 在新的线程中使用请求图片资源 ,使用GCD-(void)loadImageGCD{    //创建一个新线程    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        //在block中去执行新的任务        NSURL *url = [NSURL URLWithString:KImageUrl];        [NSThread sleepForTimeInterval:2];        NSData *data = [[NSData alloc] initWithContentsOfURL:url];        UIImage *img = [[UIImage alloc] initWithData:data];        //在主线程中更新 UI        dispatch_async(dispatch_get_main_queue(), ^{            self.imageView.image = img;        });    });}

      在这里的形式也是直接用block块,在block中执行加载图片、更新视图,不过语句相对复杂,不太易理解。

      

      三种方式,多多少少还是会容易记混,还是择其中特性进行相应的记忆。


0 0
原创粉丝点击