<一>引入dispatch_group函數的目的
在追加到dispatch_Queue中的多個處理全部結束后想要執行結束的處理,這種需求經常會在我們的程序中出現
(第一種情況)只使用一個Serial Dispatch Queue時,只要將想要執行的操作全部追加到串行隊列,並在最后執行結束的操作即可實現
(第二種情況)當我們使用Concurrent Dispatch Queue時或者使用多個Dispatch Queue時,我們想要實現這種需求變得十分復雜
(由第二種情況引出Dispatch Group)使用Dispatch Group可以實現組處理,我們可以把想要執行的操作放在操作組里,並通過監視,如果組中的操作全部執行完畢時,我們就可以執行結束處理的操作
<二>使用dispatch_group_notify函數實現組處理
dispatch_group_notify(dispatch_group_t group, dispatch_queue_t queue, ^(void)block)
dispatch_group_t group:參數指定為要監視的Dispatch Group
在被追加到第一個參數中對應的全部處理全部執行結束后,將會把第三個參數的Block追加到第二個參數的queue中
**在dispatch_group_notify函數中不管指定什么樣的Dispatch Queue,屬於Dispatch Group的全部處理在追加指定的Block時都已經執行結束

1 /*! 2 * @brief 使用dispatch_group_notify函數進行組處理 3 */ 4 - (void)groupTest1 { 5 6 //創建調度組 7 dispatch_group_t group = dispatch_group_create(); 8 //獲取全局隊列 9 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 10 //調度組的異步請求 11 dispatch_group_async(group, queue, ^{ 12 13 [NSThread sleepForTimeInterval:2]; 14 NSLog(@"下載第一張圖"); 15 }); 16 dispatch_group_async(group, queue, ^{ 17 [NSThread sleepForTimeInterval:3]; 18 19 NSLog(@"下載第二張圖"); 20 }); 21 dispatch_group_async(group, queue, ^{ 22 [NSThread sleepForTimeInterval:1]; 23 24 NSLog(@"下載第三張圖"); 25 }); 26 dispatch_group_async(group, queue, ^{ 27 [NSThread sleepForTimeInterval:5]; 28 29 NSLog(@"下載第四張圖"); 30 }); 31 //notify通知,當所有異步請求完成時調用dispatch_group_notify 32 dispatch_group_notify(group, queue, ^{ 33 NSLog(@"更新UI"); 34 }); 35 /*! 36 * @brief 輸出結果 37 * 38 2016-03-15 22:35:44.630 GCD其他方法[6766:208644] 下載第三張圖 39 2016-03-15 22:35:45.632 GCD其他方法[6766:208629] 下載第一張圖 40 2016-03-15 22:35:46.632 GCD其他方法[6766:208643] 下載第二張圖 41 2016-03-15 22:35:48.632 GCD其他方法[6766:208651] 下載第四張圖 42 2016-03-15 22:35:48.632 GCD其他方法[6766:208643] 更新UI 43 */ 44 }
<三>使用dispatch_group_wait函數實現組處理
dispatch_group_wait(dispatch_group_t group, dispatch_time_t timeout)
dispatch_time_t timeout:參數用來指定等待的時間
這里的等待表示,一旦調用dispatch_group_wait函數,該函數就處理調用的狀態而不返回值,只有當函數的currentThread停止,或到達wait函數指定的等待的時間,或Dispatch Group中的操作全部執行完畢之前,執行該函數的線程停止.
當指定timeout為DISPATCH_TIME_FOREVER時就意味着永久等待
當指定timeout為DISPATCH_TIME_NOW時就意味不用任何等待即可判定屬於Dispatch Group的處理是否全部執行結束
如果dispatch_group_wait函數返回值不為0,就意味着雖然經過了指定的時間,但Dispatch Group中的操作並未全部執行完畢
如果dispatch_group_wait函數返回值為0,就意味着Dispatch Group中的操作全部執行完畢

1 /*! 2 * @brief 使用dispatch_group_wait函數進行組處理 3 */ 4 - (void)groupTest1 { 5 6 //創建調度組 7 dispatch_group_t group = dispatch_group_create(); 8 //獲取全局隊列 9 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 10 //調度組的異步請求 11 dispatch_group_async(group, queue, ^{ 12 13 [NSThread sleepForTimeInterval:2]; 14 NSLog(@"下載第一張圖"); 15 }); 16 dispatch_group_async(group, queue, ^{ 17 [NSThread sleepForTimeInterval:3]; 18 19 NSLog(@"下載第二張圖"); 20 }); 21 dispatch_group_async(group, queue, ^{ 22 [NSThread sleepForTimeInterval:1]; 23 24 NSLog(@"下載第三張圖"); 25 }); 26 dispatch_group_async(group, queue, ^{ 27 [NSThread sleepForTimeInterval:5]; 28 29 NSLog(@"下載第四張圖"); 30 }); 31 //使用wait函數表示只要group中有操作沒有執行結束就一直等待 32 //dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 33 //NSLog(@"更新UI"); 34 /*! 35 * @brief 輸出結果 36 * 37 2016-03-15 22:35:44.630 GCD其他方法[6766:208644] 下載第三張圖 38 2016-03-15 22:35:45.632 GCD其他方法[6766:208629] 下載第一張圖 39 2016-03-15 22:35:46.632 GCD其他方法[6766:208643] 下載第二張圖 40 2016-03-15 22:35:48.632 GCD其他方法[6766:208651] 下載第四張圖 41 2016-03-15 22:35:48.632 GCD其他方法[6766:208643] 更新UI 42 */ 43 }
<三>使用dispatch_group_enter和dispatch_group_leave實現組處理
dispatch_group_enter(dispatch_group_t group)
在函數開始時調用enter函數
dispatch_group_leave(dispatch_group_t group)
在函數結束時調用leave函數

1 /*! 2 * @brief 使用dispatch_group_enter和dispatch_group_leave函數實現組處理 3 */ 4 - (void)groupTest2 { 5 6 //創建調度組 7 dispatch_group_t group = dispatch_group_create(); 8 //獲取全局隊列 9 dispatch_queue_t queue = dispatch_get_global_queue(0, 0); 10 11 //進入隊列 12 dispatch_group_enter(group); 13 dispatch_async(queue, ^{ 14 15 [NSThread sleepForTimeInterval:2]; 16 NSLog(@"下載第一張圖"); 17 18 //離開隊列 19 dispatch_group_leave(group); 20 }); 21 22 dispatch_group_enter(group); 23 dispatch_async(queue, ^{ 24 25 [NSThread sleepForTimeInterval:1]; 26 NSLog(@"下載第二張圖"); 27 28 dispatch_group_leave(group); 29 }); 30 31 dispatch_group_enter(group); 32 dispatch_async(queue, ^{ 33 34 [NSThread sleepForTimeInterval:3]; 35 NSLog(@"下載第三張圖"); 36 37 dispatch_group_leave(group); 38 }); 39 40 //等待調度隊列wait相當於一個阻塞狀態 41 dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 42 43 NSLog(@"更新UI"); 44 /*! 45 * @brief 輸出結果 46 * 47 2016-03-15 22:36:49.277 GCD其他方法[6783:209444] 下載第二張圖 48 2016-03-15 22:36:50.280 GCD其他方法[6783:209429] 下載第一張圖 49 2016-03-15 22:36:51.279 GCD其他方法[6783:209445] 下載第三張圖 50 2016-03-15 22:36:51.279 GCD其他方法[6783:209352] 更新UI 51 */ 52 53 }