GCD、及與NSOperationQueue的對比

1 線程、隊列、RunLoop

1.1 線程與隊列

  1. 線程是執行者,隊列是等待執行的任務隊列。程序員

  2. GCD是程序員告訴隊列中的任務經過什麼方式,在哪一個或哪些隊列執行。objective-c

1.2 GCD與RunLoop

  1. 對於主線程中的task queue,至關於加入到了main RunLoop的dispatch block併發

  2. 對於併發隊列中的task,至關於加入到了子線程RunLoop的dispatch block中,若是子線程尚未RunLoop會自動建立。異步

2 queue

2.1 自定義隊列

串行隊列:隊列中的任務只會順序執行async

dispatch_queue_t q = dispatch_queue_create("...", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t q = dispatch_queue_create("...", NULL);
複製代碼

並行隊列: 隊列中的任務一般會併發執行oop

dispatch_queue_t q = dispatch_queue_create("......",DISPATCH_QUEUE_CONCURRENT);
複製代碼

2.2 系統標準隊列

全局隊列:是系統的,直接GET。並行spa

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
複製代碼

主隊列:每個應用程序對應惟一主隊列,直接GET。串行 主隊列只會運行在主線程上,使用主隊列更新UI。 主線程能夠執行其餘隊列的任務。線程

dispatch_queue_t q = dispatch_get_main_queue();
複製代碼

3 同步、異步,針對的是向前線程

dispatch_sync(_queue, ^() {
    //...
}
複製代碼

4 dispatch_group

Case: 有a、b、c、d 4個異步請求,如何判斷a、b、c、d都完成執行?若是須要a、b、c、d順序執行,該如何實現?code

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{ /*任務a */ });
dispatch_group_async(group, queue, ^{ /*任務b */ });
dispatch_group_async(group, queue, ^{ /*任務c */ });
dispatch_group_async(group, queue, ^{ /*任務d */ });

//先提交,再用notify或者wait
dispatch_group_notify(group,dispatch_get_main_queue(), ^{
// 在a、b、c、d異步執行完成後,會回調這裏
});

//dispatch_group_wait(_loggingGroup, DISPATCH_TIME_FOREVER);
複製代碼

順序執行,queue用串行隊列。cdn

5 dispatch_barrier_async

  1. 在同一個queue(哪怕是並行隊列)裏面,執行順序:barrier以前的任務、barrier任務、barrier以後的任務。
  2. 只在自定義隊列上有效,在系統標準隊列上,效果等同於dispatch_sync。
//不使用barrier時
dispatch_queue_t queue = dispatch_queue_create("queue_name", DISPATCH_QUEUE_CONCURRENT);

    dispatch_async(queue, ^{
        NSLog(@"----耗時任務1-----%@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"----耗時任務2-----%@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"----耗時任務3-----%@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"----耗時任務4-----%@", [NSThread currentThread]);
    });
複製代碼

dispatch_queue_t queue = dispatch_queue_create("queue_name", DISPATCH_QUEUE_CONCURRENT);

    dispatch_async(queue, ^{
        NSLog(@"----耗時任務1-----%@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"----耗時任務2-----%@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"----耗時任務3-----%@", [NSThread currentThread]);
    });

    dispatch_barrier_async(queue, ^{
        NSLog(@"----barrier-----%@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"----耗時任務4-----%@", [NSThread currentThread]);
    });

 dispatch_async(queue, ^{
        NSLog(@"----耗時任務5-----%@", [NSThread currentThread]);
    });
複製代碼

6 dispatch_time

比NSTimer更精準

dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));

//dispatch_time的第二個參數的單位是納秒

#define NSEC_PER_SEC 1000000000ull //每秒的納秒數

複製代碼

7 任務取消

兩種方法,其中第二種方法只能中止單個任務,不能取消整個隊列的任務。

只能取消未開始的任務。

  1. 利用外部變量

  2. 利用dispatch_block_create、dispatch_block_cancel

8 對比NSOperationQueue

8.1 NSOperationQueue與GCD之間的關係

GCD是純C語言的API 。

NSOperationQueue是基於GCD的OC的封裝。

8.2 二者的不一樣

  1. GCD只支持FIFO隊列,NSOperationQueue能夠從新設置優先級,最大併發數。

  2. NSOperationQueue但是方便設置operation之間的依賴關係,GCD則須要不少代碼。

  3. NSOperationQueue支持KVO,便可以觀察任務的執行狀態,正在執行(isExecuted),是否結束(isFinished),是否取消(isCanceled)。

8.3 結論

  1. GCD更接近底層,而NSOperationQueue則更高級抽象。

  2. GCD速度更快。

  3. 任務之間的依賴關係。GCD須要本身寫更多的代碼來實現,而NSOperationQueue已經內建了這些支持。

相關文章
相關標籤/搜索