iOS多線程編程篇: Operation 對象 與 Operation Queue

概念

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: 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章