GCD中的dispatch_group函數的詳解


<一>引入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 groupdispatch_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 }
notify實現組處理

<三>使用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 }
wait函數實現組操作

 

<三>使用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 }
enter和leave實現組處理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM