概念
Operation Queues 是Cocoa版本的併發dispatch queue,由NSOperationQueue類實現。dispatch queue總是按先進先出的順序執行任務,而Operation Queues在確定任務執行順序時,還會考慮其他因素。最主要的一個因素是指定任務是否依賴兩一個任務的完成。你在定義任務時配置依賴性,從而創建負責的任務執行順序圖。
Operation objects會產生key-value observing(KVO)通知,對於監控任務的進程非常有用。雖然Operation queue總是併發地執行任務,你可以使用依賴,在需要時確保順序執行。
Operation
默認的Operation
所有Operation objects都支持以下關鍵特性
1、支持建立基於圖的opration objects依賴。可以阻止某個Operation運行,直到它依賴的所有operation都已經完成。
2、支持可選的completion block,在Operation的主任務完成後調用。
3、支持應用使用KVO通知來監控Operation的執行狀態。
4、支持Operation優先級,從而影響相對的執行順序。
5、支持取消,允許你終止正在執行的任務。
系統默認提供了兩個子類化的Operation對象:
NSInvocationOperation:可以直接使用的類,基於應用的一個對象和selector來創建Operation object。如果你已經有現有的方法來執行需要的任務,就可以使用這個類。
NSBlockOperation:可以直接使用的類,用來併發地執行一個或多個blcok對象。Operation object使用“組”的語義來執行多個block對象,所有相關的block都執行完成之後,operation object纔算完成。
Operation 任務的執行可通過兩個方式:
1、手動調起start
2、將Operation對象添加到一個初始化的Operation Queue中
以下是兩種方式開啓任務的區別:
Operation 如果手動start開啓,Operation對象內部是默認非併發地,也就是與start調用的線程是同步執行的,也就是會阻礙當前線程,如果想使用異步併發,必須在異步的併發隊列中調用start纔行。
當然也可以直接將Operation 添加到 一個初始化ok的Operation Queue中,Operation Queue會幫助你異步地調用start方法
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1");
NSLog(@"===%@", [NSThread currentThread]);
}];
[op addExecutionBlock:^{
NSLog(@"2");
NSLog(@"%@", [NSThread currentThread]);
}];
[op addExecutionBlock:^{
NSLog(@"3");
NSLog(@"%@", [NSThread currentThread]);
}];
[op addExecutionBlock:^{
NSLog(@"4");
NSLog(@"%@", [NSThread currentThread]);
}];
[op setCompletionBlock:^{
NSLog(@"併發完成");
}];
NSLog(@"done");
// operation是非併發對象
// 這樣在主線程中執行的話,與主線程同步,輸出 1、2、3、4亂序 再輸出done
[op start]; //Operation線程 與 主線程 同步 ,非併發
//主線程與op屬於併發(不知道是誰先運行)
//輸出 1、2、3、4、done都是亂序的 屬於併發
//第一種方式
[queue addOperation:op]; //異步執行,併發執行
//
// //第二種方式
// dispatch_async(dispatch_get_global_queue(0, 0), ^{
//
// [op start]; //這句代碼和下句代碼是線程同步的
//
// dispatch_async(dispatch_get_main_queue(), ^{
//
// NSLog(@"網絡請求完成");
// });
//
// });
自定義Operation
如果系統子類化的Operation 無法滿足您的需求,你可以自定義Operation,重寫它的一些方法,達到你的目的。
1、定義非併發地Operation
2、定義併發地Operation (因爲Operation默認是非併發的,必須添加到Operation queue或者併發隊列中才能實現併發,如果你想手工實現併發地話,就必須自定義實現,設置isConcurrent爲YES)
NSOperation key-value observing KVO key paths:
isCancelled
isConcurrent
isExecuting
isFinished
isReady
dependencies
queuePriority
completionBlock
設置Operation間的依賴
注意:依賴不能循環依賴
addDependency:
設置Operation優先級
setQueuePriority:
Operation Queue
創建Queue
NSOperationQueue* aQueue = [[NSOperationQueue alloc] init];
添加Operation
[aQueue addOperation:anOp]; // Add a single operation
[aQueue addOperations:anArrayOfOps waitUntilFinished:NO]; // Add multiple operations
[aQueue addOperationWithBlock:^{ /* Do something. */
}];
設置最大併發數
setMaxConcurrentOperationCount:
取消Queue
cancel
cancelAllOperations
掛起和繼續Queue
setSuspended: