1. 程式人生 > >IOS —— NSOperation的作用以及其與GCD的區別 - 隨筆

IOS —— NSOperation的作用以及其與GCD的區別 - 隨筆

哈嘍,每日分享時間。今天要說說的是NSOperation這個類,以及和GCD的關係和區別

事不宜遲


1.NSOperation是什麼? 

我們知道,GCD是基於底層C語言封裝的API。那麼NSOperation是什麼呢?

"燈燈燈燈" 揭曉答案

NSOperation實際上是基於GCD的Objective-C語言封裝的物件。也就是所謂的父子關係。

既然是父子關係,倆者肯定有區別

那麼區別是什麼呢?

1.GCD是無法取消加入到佇列中的任務的,而NSOperation則可以取消未執行任務。注意是未執行。

2.GCD佇列任務執行順序是先進先出(FIOI)也就是先進佇列的任務先執行

,而NSOperation可以隨意調配任務執行順序

備註:GCD任務雖然也可以進行調配,但是需要複雜繁瑣的程式碼及功能塊進行控制(barrier、group等)

3.NSOperation任務支援KVO(監聽),可以方便監聽任務狀態(開始,執行中,結束等),而GCD則不支援。

4.NSOperation可以設定同一佇列中的任務優先順序,也可以設定併發任務的執行順序。GCD只能設定不同佇列的執行優先順序

5.NSOperation支援自定義,可以封裝繁瑣複雜任務程式碼,提高複用性。GCD則不能。

 

2.NSOperation怎麼用?

1.NSOperation本身是不能直接使用的抽象類。可以通過使用系統自帶的子類NSInvocationOperation

/NSBlockOperation,或則是使用自行封裝的Operation子類

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~