線程是執行者,隊列是等待執行的任務隊列。程序員
GCD是程序員告訴隊列中的任務經過什麼方式,在哪一個或哪些隊列執行。objective-c
對於主線程中的task queue,至關於加入到了main RunLoop的dispatch block併發
對於併發隊列中的task,至關於加入到了子線程RunLoop的dispatch block中,若是子線程尚未RunLoop會自動建立。異步
串行隊列:隊列中的任務只會順序執行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);
複製代碼
全局隊列:是系統的,直接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();
複製代碼
dispatch_sync(_queue, ^() {
//...
}
複製代碼
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
//不使用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]);
});
複製代碼
比NSTimer更精準
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));
//dispatch_time的第二個參數的單位是納秒
#define NSEC_PER_SEC 1000000000ull //每秒的納秒數
複製代碼
兩種方法,其中第二種方法只能中止單個任務,不能取消整個隊列的任務。
只能取消未開始的任務。
利用外部變量
利用dispatch_block_create、dispatch_block_cancel
GCD是純C語言的API 。
NSOperationQueue是基於GCD的OC的封裝。
GCD只支持FIFO隊列,NSOperationQueue能夠從新設置優先級,最大併發數。
NSOperationQueue但是方便設置operation之間的依賴關係,GCD則須要不少代碼。
NSOperationQueue支持KVO,便可以觀察任務的執行狀態,正在執行(isExecuted),是否結束(isFinished),是否取消(isCanceled)。
GCD更接近底層,而NSOperationQueue則更高級抽象。
GCD速度更快。
任務之間的依賴關係。GCD須要本身寫更多的代碼來實現,而NSOperationQueue已經內建了這些支持。