OC - 14.NSOperation与NSOperationQueue
简介
- 通过NSOperation与NSOperationQueue的组合也能实现多线程
- 通常将任务封装成NSOperation对象,并将对象添加到NSOperationQueue中实现
NSOperation
- NSOperation是一个抽象类,不能用来直接封装操作,通常使用它的子类来封装操作
-
若不将NSOperation对象添加到NSOperationQueue中,操作只会在当前线程执行,且需要手动开始执行操作
-
NSoperation的子类
-
NSInvocationOperation
//创建操作 NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil]; //开始执行操作 [operation start];
-
NSBlockOperation(当操作数大于1时,异步执行)
//创建操作 NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ //操作封装的任务代码 }]; //添加操作 [operation addExecutionBlock:^{ //操作封装的任务代码 }]; //开始执行操作 [operation start];
-
自定义子类的步骤
- 重写- (void)main方法,在该方法中封装需要执行的操作
- 在- (void)main方法中,需要自己建立自动释放池(原因:若是异步操作,无法访问主线程的自动释放池)
- 通过检查cancelled等属性,来判断操作的状态,执行相应的操作
-
-
设置操作完成时的回调
//创建操作 NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ //任务代码 }]; //设置回调 operation.completionBlock = ^{ //操作完成时执行的代码 };
NSOperationQueue
-
作用
- 容纳需要异步执行的操作
- 系统会自动执行NSOperationQueue中的操作,不需要手动启动
-
NSOperationQueue的相关操作
-
创建操作队列
- [[NSOperationQueue alloc] init]
-
获取主操作队列
- + (NSOperationQueue *)mainQueue
-
获取当前操作队列
- + (nullable NSOperationQueue *)currentQueue
-
往队列中添加操作
- - (void)addOperation:(NSOperation *)op
- - (void)addOperationWithBlock:(void (^)(void))block
-
设置最大并发操作数
- - setMaxConcurrentOperationCount:(NSInteger)count
- 若并发操作数为1,则为串行队列
-
暂停/启动队列中的任务
- - setSuspended:(BOOL)b
-
取消队列中的任务
- - (void)cancelAllOperations
- 等到正在执行的任务执行完毕,队列才会被挂起
-
实现多线程的步骤
-
创建操作队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init]
-
往队列中添加操作
/** 方法一 */ //创建操作 NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil] //download为操作封装的任务方法 NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ //任务代码 }]; //添加操作 [queue addOperation:operation1]; [queue addOperation:operation2]; /** 方法二 */ //添加操作 [queue addOperationWithBlock:^{ //操作封装的任务 }];
操作依赖
-
作用
- 建立操作之间的执行顺序关系
- 操作依赖是面向操作的,可以跨队列建立操作之间的依赖关系
- 若要建立操作之间的依赖关系,必须在操作被添加到队列之前建立
-
建立操作依赖的步骤
-
创建操作队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init]
-
添加操作
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ //任务1代码 }]; NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ //任务2代码 }];
-
建立依赖关系(必须在操作被添加到队列之前)
[operation1 addDependency:operation2];
-
将操作添加到队列
[queue addOperation:operation1]; [queue addOperation:operation2];
-
线程之间的通信
-
从主线程到子线程
- 从主线程到子线程的切换,通常是系统自动完成的,只需要将操作添加到队列中,系统就会根据实际需要,是否切换到子线程中执行操作
-
从子线程到主线程
-
将需要执行的操作,添加到主操作队列中即可(该操作将运行在主runLoop的common模式下)
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ //需要在主线程中执行的任务代码 }];
-