前言
? ? ?面對復雜多變的需求,有時候需要用到線程的暫停、取消拿霉、監(jiān)聽等缸废,這里在 NSOperation 基礎用法 的基礎上進行進階拓展包蓝。關于本文以及NSOperation 基礎用法 的代碼Demo驶社,我放在了我的github上,可以去下載來看一下测萎,因為這個是Demo所以也覺得大家沒必要給star亡电,以后我會在github上造一些輪子,到時候如果大家覺得好用的話硅瞧,勞煩給個star份乒,如果有什么疑惑或者覺得我有哪些不對,迫切希望來技術討論腕唧。
正文
1或辖、 取消 、 暫停 和恢復
(1)取消
可以直接調用NSOperationQueue的cancelAllOperations方法枣接,也可以逐個Operation取消颂暇。
取消了一個操作時,它不會立刻停止但惶。它需要再次進入“main”函數(shù)中耳鸯,檢查到isCancelled == YES 時被取消掉;否則膀曾,操作會一直執(zhí)行到完成為止县爬。
(2)暫停 和 恢復
通過suspended 的 setter方法來設定暫停或恢復添谊。
2捌省、操作優(yōu)先級
通過 queuePriority 的setter 方法和getter方法 進行優(yōu)先級操作
系統(tǒng)提供了以下幾個優(yōu)先級:
3、操作依賴
(1)NSOperation之間可以設置依賴來保證執(zhí)行順序碉钠,?如一定要讓操作A執(zhí)行完后,才能執(zhí)行操作B,可以像下面這么寫
[operationB addDependency:operationA]; // 操作B依賴于操作
(2)可以在不同queue的NSOperation之間創(chuàng)建依賴關系
4纲缓、監(jiān)聽
(1)completionBlock
通過completionBlock 這個block可以監(jiān)聽到operation操作結束。
?@property(nullable,copy)void(^completionBlock)(void)NS_AVAILABLE(10_6,4_0);
(2)KVO
可以通過KVO 監(jiān)聽 Operation 的isExecuting, isFinished, isConcurrent 和 isReady等屬性喊废,來判斷相對應狀態(tài)祝高。
5、自定義子類
NSOperation的子類化一般都是采取重寫start污筷、main方法工闺。當重寫“start”方法時,必須處理好isExecuting, isFinished, isConcurrent 和 isReady這些屬性瓣蛀。否則會導致操作類部分功能失效陆蟆。
關于start方法與main方法的執(zhí)行時機,可以粗略這樣理解:operation加入queque時直接執(zhí)行main惋增,不調用start叠殷;調用start方法時,在start方法中調用main方法诈皿。
代碼如下林束,我放了一份Demo代碼在我的github上像棘,可以下載參考一下。
-(instancetype)initWithOperationBlock:(OperationBlock)operationBlock {
self= [superinit];
if(self) {
_isAsyn=YES;
_operationBlock= operationBlock;
}
returnself;
}
//NSOperation的子類化一般都是采取重寫start main方法壶冒,但是也可以自己實現(xiàn)其他方法,可以參考一下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];
}