参考博客:NSOperation简介
【iOS】NSOperation, NSOperationQueue
NSOperation的简单介绍
NSOperation 是居于objective-c对GCD封装居于面向对象的,线程执行方式;NSOperation配合NSOperationQueue也能实现多线程编程;
NSOperation和NSOperationQueue实现多线程的具体步骤:
- 先将需要执行的操作封装到一个NSOperation对象中
- 然后将NSOperation对象添加到NSOperationQueue中
- 将取出的NSOperation封装的操作放到一条新线程中执行
NSOperation,NSOperationQueue常用属性和方法归纳
NSOperation常用属性和方法
- 取消操作cancel
- 判断操作状态方法
- isFinished判断操作是否已经结束
- isCancelled判断操作是否取消
- is Excuting判断操作是否正在运行
- isReady判断是否处于就绪状态
- isAsynchronous表示任务是并发还是同步执行
- 操作同步
- waitUntilFinished阻塞当前线程
- setCompletionBlock:(void(^)(void))block;当前操作完毕之后执行block
- addDependency添加依赖
- removeDependency移除依赖
- @property (readonly, copy) NSArray<NSOperation *> *dependencies;数组存储操作
NSOperationQueue的常用属性和方法
- 取消/暂停/恢复队列中的操作
- cancelAllOperations;取消队列中所有的操作
- isSuspended判断队列是否处理暂停状态 YES:暂停状态,NO恢复状态
- setSuspended:(BOOL)b;设置操作的暂停和恢复 YES:暂停,NO:恢复
- 同步操作
- waitUntilAllOperationsAreFinished;阻塞当前线程,直到队列中的操作全部完成
- 添加/获取
- addOperationWithBlock:(void (^)(void))block向队列中添加一个NSBlockOperation类型的操作对象
- addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait;添加操作数组,wait标志是否阻塞当前线程知道所有操作结束
- operations当前在队列中的操作数组
- operationCount操作个数
- 获取队列
- currentQueue当前队列,如果当前线程不在Queue上,返回nil
- mainQueue获取主队列
暂停和取消
暂停和取消(包括操作的取消和队列的取消)并不代表可以将当前的操作立即取消,而是当当前的操作执行完毕之后不再执行新的操作。
暂停和取消的区别在于:暂停操作之后还可以恢复操作,而取消操作之后,所有的操作就清空了,无法在接着执行剩下的操作。
NSOperation的使用方法
NSOperation是一个抽象类,本身并不具备封装操作的能力,必须使用其子类。使用NSOperation的子类有两种方式,使用apple提供的现有的子类NSInvocationOperation、NSBlockOperation以及自定义子类继承NSOperation实现内部相应的方法。现简单说明系统提供的子类的使用。
NSInvocationOperation
不配合NSOperationQueue使用的话是在当前线程中串行执行,不会开启新线程。
1.创建操作,封装任务
- 第一个参数:目标对象 self
- 第二个参数:调用方法的名称
- 第三个参数:前面方法需要接受的参数 nil
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:<#(nonnull id)#> selector:<#(nonnull SEL)#> object:<#(nullable id)#>];
2.启动1执行操作
[op1 start];
NSBlockOperation
1.创建操作
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
/*code*/
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
/*code*/
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
/*code*/
}];
追加任务(开启子线程)
//注意:如果一个操作中的任务量大于1,那么会开子线程并发执行任务
//注意:不一定是子线程,有可能是主线程
[op1 addExecutionBlock:^{
/*code*/
}];
[op2 addExecutionBlock:^{
/*code*/
}];
[op3 addExecutionBlock:^{
/*code*/
}];
2.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
3.添加操作到队列中
[queue addOperation:op1]; // 内部已经调用了[op1 start];
[queue addOperation:op2];
[queue addOperation:op3];
简便方法
1&