ios多線程操作— GCD調度組
有這麼一個需要,分別執行2個耗時的非同步作業,等2個非同步作業都執行完畢後在回到主線程執行操作。如果想要快速高效地實現這個需求,可以考慮使用調度組。 調度組的建立代碼如下:
dispatch_group_t group = dispatch_group_create();
往調度組裡面新增工作的函數如下:
dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, ^(void)block)
第一個參數group是一個調度組,queue是一個非同步隊列,這裡如果使用同步隊列意義就不大了,不過還是能達到效果,第三個參數是一個執行代碼塊,任務都添加到該代碼塊裡面。 往調度組裡面新增工作並獲得通知的代碼如下:
// 群組-統一監控一組任務 dispatch_group_t group = dispatch_group_create(); dispatch_queue_t q = dispatch_get_global_queue(0, 0); // 新增工作 // group 負責監控任務,queue 負責調度任務 dispatch_group_async(group, q, ^{ [NSThread sleepForTimeInterval:1.0]; NSLog(@"任務1 %@", [NSThread currentThread]); }); dispatch_group_async(group, q, ^{ NSLog(@"任務2 %@", [NSThread currentThread]); }); dispatch_group_async(group, q, ^{ NSLog(@"任務3 %@", [NSThread currentThread]); }); // 監聽所有任務完成 - 等到 group 中的所有任務執行完畢後,"由隊列調度 block 中的任務非同步執行!" dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // 修改為主隊列,後台批量下載,結束後,主線程統一更新UI NSLog(@"OK %@", [NSThread currentThread]); }); NSLog(@"come here");
代碼的執行結果如下:
其中任務的下載順序以及"come here”出現的地方不確定,但主線程的更新操作總會在最後才執行!
GCD調度組中還有一個新增工作的函數: dispatch_group_enter(dispatch_group_t group) dispatch_group_leave(dispatch_group_t group) 這兩個函數要配對出現 例如:
// 群組-統一監控一組任務 dispatch_group_t group = dispatch_group_create(); dispatch_queue_t q = dispatch_get_global_queue(0, 0); // 1> 入組 -> 之後的 block 會被 group 監聽 // dispatch_group_enter 一定和 dispatch_group_leave 要配對出現 dispatch_group_enter(group); dispatch_async(q, ^{ NSLog(@"task1 %@", [NSThread currentThread]); // block 的末尾,所有任務執行完畢後,添加一個出組 dispatch_group_leave(group); }); // 再次入組 dispatch_group_enter(group); dispatch_async(q, ^{ [NSThread sleepForTimeInterval:1.0]; NSLog(@"task2 %@", [NSThread currentThread]); // block 的末尾,所有任務執行完畢後,添加一個出組 dispatch_group_leave(group); }); // 群組結束 dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"OVER"); }); NSLog(@"come here");
代碼執行的效果與剛才那種方式相同! GCD中還有一個函數
dispatch_group_wait(dispatch_group_t group, dispatch_time_t timeout)
該函數是個阻塞式的等待,當我們將第二個參數設定為DISPATCH_TIME_FOREVER時,群組任務不執行完,後續代碼就會無法執行,也就是說只要任務不執行完come here就不會列印。