前言
面对复杂多变的需求,有时候需要用到线程的暂停、取消、监听等,这里在 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上,可以下载参考一下。
-(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];
}