前言
面对复杂多变的需求,有时候需要用到线程的暂停、取消、监听等,这里在 NSOperation 基础用法 的基础上进行进阶拓展。关于本文以及NSOperation 基础用法 的代码Demo,我放在了我的github上,可以去下载来看一下,因为这个是Demo所以也觉得大家没必要给star,以后我会在github上造一些轮子,到时候如果大家觉得好用的话,劳烦给个star,如果有什么疑惑或者觉得我有哪些不对,迫切希望来技术讨论。
正文
1、 取消 、 暂停 和恢复
(1)取消
可以直接调用NSOperationQueue的cancelAllOperations方法,也可以逐个Operation取消。
取消了一个操作时,它不会立刻停止。它需要再次进入“main”函数中,检查到isCancelled == YES 时被取消掉;否则,操作会一直执行到完成为止。
(2)暂停 和 恢复
通过suspended 的 setter方法来设定暂停或恢复。
2、操作优先级
通过 queuePriority 的setter 方法和getter方法 进行优先级操作
系统提供了以下几个优先级:
3、操作依赖
(1)NSOperation之间可以设置依赖来保证执行顺序,⽐如一定要让操作A执行完后,才能执行操作B,可以像下面这么写
[operationB addDependency:operationA]; // 操作B依赖于操作

(2)可以在不同queue的NSOperation之间创建依赖关系
4、监听
(1)completionBlock
通过completionBlock 这个block可以监听到operation操作结束。
@property(nullable,copy)void(^completionBlock)(void)NS_AVAILABLE(10_6,4_0);
(2)KVO
可以通过KVO 监听 Operation 的isExecuting, isFinished, isConcurrent 和 isReady等属性,来判断相对应状态。
5、自定义子类
NSOperation的子类化一般都是采取重写start、main方法。当重写“start”方法时,必须处理好isExecuting, isFinished, isConcurrent 和 isReady这些属性。否则会导致操作类部分功能失效。
关于start方法与main方法的执行时机,可以粗略这样理解:operation加入queque时直接执行main,不调用start;调用start方法时,在start方法中调用main方法。
代码如下,我放了一份Demo代码在我的github上,可以下载参考一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
-(instancetype)initWithOperationBlock:(OperationBlock)operationBlock { self= [superinit]; if(self) { _isAsyn=YES; _operationBlock= operationBlock; } returnself; } //NSOperation的子类化一般都是采取重写start main方法,但是也可以自己实现其他方法,可以参考一下AFNetWorking -(void)start { //同步情况是才会调用start _isAsyn=NO; if(self.cancelled) {//被取消 _isFinished=YES; }else{//未被取消 _isExecuting=YES; [selfmain]; } } -(void)main { @autoreleasepool{ void(^cancelBlock)() = ^() { _isExecuting=NO; _isFinished=YES; }; if(!self.isCancelled) { _operationBlock(); cancelBlock(); } } } //重写getter方法是为了在外部能完整获取相关信息 #pragma mark重写getter方法 -(BOOL)isFinished { return_isFinished; } -(BOOL)isConcurrent{ return!_isAsyn; } -(BOOL)isExecuting { return_isExecuting; } #pragma mark Class Method //异步 +(void)asynOperationBlock:(OperationBlock)operationBlock { WXSOperation*operation = [[WXSOperationalloc]init]; operation.operationBlock= [operationBlockcopy]; NSOperationQueue*queue = [[NSOperationQueuealloc]init]; [queueaddOperation:operation]; } //同步 +(void)synOperationBlock:(OperationBlock)operationBlock { WXSOperation*operation = [[WXSOperationalloc]initWithOperationBlock:operationBlock]; //如果添加到queue里,依然是异步 [operationstart]; } |