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 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 }