前言
? ? ?面對復(fù)雜多變的需求,有時候需要用到線程的暫停、取消、監(jiān)聽等,這里在 NSOperation 基礎(chǔ)用法 的基礎(chǔ)上進(jìn)行進(jìn)階拓展。關(guān)于本文以及NSOperation 基礎(chǔ)用法 的代碼Demo,我放在了我的github上,可以去下載來看一下,因為這個是Demo所以也覺得大家沒必要給star,以后我會在github上造一些輪子,到時候如果大家覺得好用的話,勞煩給個star,如果有什么疑惑或者覺得我有哪些不對,迫切希望來技術(shù)討論。
正文
1、 取消 、 暫停 和恢復(fù)
(1)取消
可以直接調(diào)用NSOperationQueue的cancelAllOperations方法,也可以逐個Operation取消。

取消了一個操作時,它不會立刻停止。它需要再次進(jìn)入“main”函數(shù)中,檢查到isCancelled == YES 時被取消掉;否則,操作會一直執(zhí)行到完成為止。
(2)暫停 和 恢復(fù)
通過suspended 的 setter方法來設(shè)定暫?;蚧謴?fù)。

2、操作優(yōu)先級
通過 queuePriority 的setter 方法和getter方法 進(jìn)行優(yōu)先級操作


系統(tǒng)提供了以下幾個優(yōu)先級:

3、操作依賴
(1)NSOperation之間可以設(shè)置依賴來保證執(zhí)行順序,?如一定要讓操作A執(zhí)行完后,才能執(zhí)行操作B,可以像下面這么寫
[operationB addDependency:operationA]; // 操作B依賴于操作

(2)可以在不同queue的NSOperation之間創(chuàng)建依賴關(guān)系
4、監(jiān)聽
(1)completionBlock
通過completionBlock 這個block可以監(jiān)聽到operation操作結(jié)束。
?@property(nullable,copy)void(^completionBlock)(void)NS_AVAILABLE(10_6,4_0);

(2)KVO
可以通過KVO 監(jiān)聽 Operation 的isExecuting, isFinished, isConcurrent 和 isReady等屬性,來判斷相對應(yīng)狀態(tài)。
5、自定義子類
NSOperation的子類化一般都是采取重寫start、main方法。當(dāng)重寫“start”方法時,必須處理好isExecuting, isFinished, isConcurrent 和 isReady這些屬性。否則會導(dǎo)致操作類部分功能失效。
關(guān)于start方法與main方法的執(zhí)行時機(jī),可以粗略這樣理解:operation加入queque時直接執(zhí)行main,不調(diào)用start;調(diào)用start方法時,在start方法中調(diào)用main方法。
代碼如下,我放了一份Demo代碼在我的github上,可以下載參考一下。
-(instancetype)initWithOperationBlock:(OperationBlock)operationBlock {
self= [superinit];
if(self) {
_isAsyn=YES;
_operationBlock= operationBlock;
}
returnself;
}
//NSOperation的子類化一般都是采取重寫start main方法,但是也可以自己實現(xiàn)其他方法,可以參考一下AFNetWorking
-(void)start {
//同步情況是才會調(diào)用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方法是為了在外部能完整獲取相關(guān)信息
#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];
}