IOS —— NSOperation的作用以及其與GCD的區別 - 隨筆
哈嘍,每日分享時間。今天要說說的是NSOperation這個類,以及和GCD的關係和區別
事不宜遲
1.NSOperation是什麼?
我們知道,GCD是基於底層C語言封裝的API。那麼NSOperation是什麼呢?
"燈燈燈燈" 揭曉答案
NSOperation實際上是基於GCD的Objective-C語言封裝的物件。也就是所謂的父子關係。
既然是父子關係,倆者肯定有區別
那麼區別是什麼呢?
1.GCD是無法取消加入到佇列中的任務的,而NSOperation則可以取消未執行任務。注意是未執行。
2.GCD佇列任務執行順序是先進先出(FIOI)也就是先進佇列的任務先執行
備註:GCD任務雖然也可以進行調配,但是需要複雜繁瑣的程式碼及功能塊進行控制(barrier、group等)
3.NSOperation任務支援KVO(監聽),可以方便監聽任務狀態(開始,執行中,結束等),而GCD則不支援。
4.NSOperation可以設定同一佇列中的任務優先順序,也可以設定併發任務的執行順序。GCD只能設定不同佇列的執行優先順序
5.NSOperation支援自定義,可以封裝繁瑣複雜任務程式碼,提高複用性。GCD則不能。
2.NSOperation怎麼用?
1.NSOperation本身是不能直接使用的抽象類。可以通過使用系統自帶的子類NSInvocationOperation
2.Operation物件都是呼叫start方法執行任務的。也有例外,比如說"NSOperationQueue"
例:
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector('物件方法') object:nil]; [op start];
那麼子類NSInvocationOperation/NSBlockOperation 倆者又有何區別?
1.當單獨使用NSInvocationOperation時,NSInvocationOperation是在主執行緒
2.當使用NSBlockOperation時,NSBlockOperation是在主執行緒進行同步執行操作。新增子執行緒進行併發執行操作。
對的沒錯是本體,NSBlockOperation本身具備新增子執行緒方法"addExeutionBlock"。以下是例子。
['例項物件' addExecutionBlock:^{ //方法 }];
大致講完子類,我們來說說另外一種啟動方式:NSOperationQueue
如果不用start啟動NSOperation子類進行操作任務的話,也可以通過將子類物件直接新增到操作物件佇列中直接執行任務,並且預設開啟新執行緒,執行的是併發操作。
直接新增的方式有倆種以下程式碼示例~~
//通過方法新增 //<1> :- (void)addOperation:(NSOperation *)op; ["例項的佇列物件" addOperation:"Op物件"]; //通過block直接新增 // <2>: - (void)addOperationWithBlock:(void (^)(void))block; ["例項的佇列物件" addOperationWithBlock:^{ }];
3.NSOperation還有什麼用?
1.新增依賴
NSOperation可以通過新增依賴來操作物件的先後執行順序。
新增方法:addDependency:
刪除方法:removeDependency:
例: 假設任務一依賴於任務二
['任務1' addDeperdency:'任務2'];
新增依賴後,此時的任務1需要在任務2執行完畢後,才會執行。
注意事項:
1.如果任務出現互相依賴的情況,那麼程式將會陷入死迴圈loop。
2.當被依賴的任務2未執行的情況下,執行任務1時。程式將會執行失敗,並且報錯。
3.依賴關係必須在任務新增到佇列前才會有效。
4.新增依賴的操作物件必須等待所有操作完成時(操作在未執行的情況下被取消也算作完成),才會執行操作。
2.取消
NSOperation可以通過指令來取消物件未執行的操作。注意,是未 執 行。已執行、操作中的物件是不能被取消的。
//單項取消未 執 行 操作 ['任務1' cancel]; //取消所有未執行的操作 ['執行緒' cancelAllOperation];
3.優先順序
NSOperation可以通過優先順序指令來設定同一佇列的操作順序先後。
//這是優先順序函式 typedef NS_ENUM(NSInteger, NSOperationQueuePriority) { NSOperationQueuePriorityVeryLow = -8L, NSOperationQueuePriorityLow = -4L, NSOperationQueuePriorityNormal = 0, NSOperationQueuePriorityHigh = 4, NSOperationQueuePriorityVeryHigh = 8 }; //這是使用方法 ['任務1' setOperationPriorty:NSOperationQueuePriorityNormal];
注意事項:操作優先順序並不是絕對優先的,還需要看當前操作的依賴關係以及操作加入佇列的順序。當加入的操作依賴關係未處理,或者晚於同優先順序操作進入佇列時,當前操作將會延後處理。
4.暫停、繼續
NSOperation可以通過指令簡單的阻止新操作的執行,並且不會打斷正在執行的操作。
//這是程式碼 queue代表當前執行緒 //暫停 [self.queue setSuspendecl:YES]; //結束暫停 [self.queue setSuspendecl:NO];
5.監聽狀態
NSOperation的操作物件中,開發者提供了以下五種監聽狀態給開發者
1.isExcuting ,該狀態代表任務執行中。
2.isFinished ,該狀態代表任務結束。當isFinished = YES時,其他依賴操作佇列才會開始執行。操作佇列也是根據這狀態判斷決定是否將操作任務移出佇列
3.isCancel ,該狀態代表任務已經取消執行。
4.isAsynchronours ,該狀態表示任務是同步執行還是非同步執行。
5.isReady ,該狀態表示任務準備中,一般作用於有依賴任務的任務。一般isReady = NO。當依賴任務isFinished = Yes時,isReady 才會將當前狀態改為YES;
學習總結:
即使說NSOperation功能眾多而且便利,但是多數多執行緒操作一般都交於GCD處理,因為GCD更靠近底層程式碼,速度快這是關鍵。只有部分特殊要求(取消任務、設定任務執行順序、監聽任務狀態、封裝任務操作等)才會用到。
over~