22day NSOperation

来源:互联网 发布:姚明身体数据 编辑:程序博客网 时间:2024/05/29 07:38

前言

重点:
NSThread

多线程基础、pthread、开启线程的3种方式线程的状态、线程安全问题、线程间的通信

GCD

同步方法和异步方法、队列的使用、线程间的通信延迟执行、一次性代码、队列组、单例模式-ARC、单例模式-MRC、用宏抽取单例模式

NSOperation

NSOperation和NSOperationQueue的概念理解、NSInvocationOperation、NSBlockOperationNSOperationQueue的常见方法、最大并发数、操作依赖、队列的取消\暂\恢

简介

NSOperation实例 封装了需要执行的操作 和 执行操作所需的数据,并且能够以并发或非并发的方式执行这个操作.
作用:NSOperation 配合使用NSOperationQueue 实现多线程编程
NSOperation本身是抽象基类,因此必须使用它的子类,使用NSOperation子类的方式有2种:

           1> Foundation框架提供了两个具体子类直接供我们使用:NSInvocationOperationNSBlockOperation           2> 自定义子类继承NSOperation,实现内部相应的方法

*NSInvocationOperation

基于一个对象和selector来创建操作。如果你已经有现有的方法来执行需要的任务,就可以使用这个类

*NSBlockOperation

能够并发地执行一个或多个block对象,所有相关的block都执行完之后,操作才算完成

自定义定义NSOperation–(通常用于下载多张图片)

定义非并发的NSOperation要简单许多,只需要重载-(void)main这个方法,在这个方法里面执行主任务,并正确地响应取消事件;**对于并发NSOperation, 你必须重写NSOperation的多个基本方法进行实现**ps: 大量的图片处理框架推荐:SDWebImage

自定义operation的注意事项

cell的图片下载04-自定义Operation/** 自定义operation的注意点 1.如果是异步操作,无法访问主线程的自动释放池 2、经常检测操作是否被取消 */- (void)main{    @autoreleasepool {//创建自动释放池        if (self.isCancelled) {//检测操作是否被取消            return;        }        //下载图片        [NSThread sleepForTimeInterval:5];        NSURL *nsurl = [NSURL URLWithString:self.imageUrl];        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:nsurl]];        if (self.isCancelled) {            return;        }        //回到主线程        [[NSOperationQueue mainQueue] addOperationWithBlock:^{            //通知代理对象            if ([self.delegate respondsToSelector:@selector(downloadOperation:didFinishDownloadImage:)]) {                [self.delegate downloadOperation:self didFinishDownloadImage:image];            }        }];    }}

NSOperationQueue

1)简介一个NSOperation对象可以通过调用start方法来执行任务,默认是同步执行的。也可以将NSOperation添加到一个NSOperationQueue(操作队列)中去执行,而且是异步执行的。2)Operations的执行顺序先满足依赖关系,然后再根据优先级从所有准备好的操作中选择优先级最高的那个执行。

01-队列的基本用法
1)实现多线程的具体步骤
将需要执行的操作封装到NSOperation对象
将NSOperation对象添加到NSOperationQueue中
p s: 系统会自动将NSOperationQueue中的NSOperation取出,将取出的NSOperation封装的操作放到一个新的线程中执行。
2) 正确响应取消事件
以下地方可能需要调用isCancelled:

* 在执行任何实际的工作之前* 在循环的每次迭代过程中,如果每个迭代相对较长可能需要调用多次* 代码中相对比较容易中止操作的任何地方

02-队列的其他用法

1)线程间通信
主队列的使用

//回到主线程      //        self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>      //        dispatch_async(dispatch_get_main_queue(), <#^(void)block#>)      [[NSOperationQueue mainQueue]addOperationWithBlock:^{          //显示图片          [vc.imageView setImage:image];          NSLog(@"%s-------%@",__func__,[NSThread currentThread]);      };

2)队列的取消、暂停、恢复
在响应用户请求时,暂停一个queue来暂停等待中的任务。稍后根据用户的请求,可以再次调用setSuspended:方法继续queue中operation。--

/队列的暂停、恢复    [[NSOperationQueue mainQueue] setSuspended:NO];//恢复    [[NSOperationQueue mainQueue] setSuspended:YES];//暂停    [[NSOperationQueue mainQueue] cancelAllOperations];//Cancels all queued and executing operations.