【前言】
假设我们有这样一个需求:
有三个异步操作(例:网络请求ABC),想在三个请求全部执行完返回结果后,再做其他操作。
1、这三个网络请求,执行无序,并发执行。
2、不论返回失败还是成功都算返回结果。
那我们如何处理多线程的关系呢?
【探究】
如果满足上面的需求,使用GCD里面的dispatch_group_enter
和dispatch_group_leave
来实现。这边我们使用了dispatch_after ()
来模拟网络请求的异步耗时操作。
dispatch_group_enter
:通知 group,下个任务要放入 group 中执行了。
dispatch_group_leave
:通知 group,任务成功完成,要移除,与enter()
成对出现。
dispatch_group_notify
:只要任务组完成才会调用,不完成不会调用。
代码示例
- (void)viewDidLoad {
[super viewDidLoad];
[self asynchronousTaskTest];
}
/** 异步任务测试 */
- (void)asynchronousTaskTest{
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// ****************** 任务A,异步执行1秒 ************************
dispatch_group_enter(group);
NSLog(@"任务A准备开始");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), queue, ^{
NSLog(@"任务A准备结束-1");
dispatch_group_leave(group);
NSLog(@"任务A已经结束-1");
});
// ****************** 任务B,异步执行2秒 ************************
dispatch_group_enter(group);
NSLog(@"任务B准备开始");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), queue, ^{
NSLog(@"任务B准备结束-2");
dispatch_group_leave(group);
NSLog(@"任务B已经结束-2");
});
// ****************** 任务C,异步执行3秒 ************************
dispatch_group_enter(group);
NSLog(@"任务C准备开始");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), queue, ^{
NSLog(@"任务C准备结束-3");
dispatch_group_leave(group);
NSLog(@"任务C已经结束-3");
});
// ****************** 所有任务完成 ************************
dispatch_group_notify(group, queue, ^{
NSLog(@"所有任务全部完成");
});
}
结果打印如下
2020-08-13 10:20:28.737705+0800 CZProjectTestDemo[7511:1250505] 任务A准备开始
2020-08-13 10:20:28.737815+0800 CZProjectTestDemo[7511:1250505] 任务B准备开始
2020-08-13 10:20:28.737859+0800 CZProjectTestDemo[7511:1250505] 任务C准备开始
2020-08-13 10:20:29.779764+0800 CZProjectTestDemo[7511:1250557] 任务A准备结束-1
2020-08-13 10:20:29.780080+0800 CZProjectTestDemo[7511:1250557] 任务A已经结束-1
2020-08-13 10:20:30.861132+0800 CZProjectTestDemo[7511:1250557] 任务B准备结束-2
2020-08-13 10:20:30.861471+0800 CZProjectTestDemo[7511:1250557] 任务B已经结束-2
2020-08-13 10:20:32.029025+0800 CZProjectTestDemo[7511:1250553] 任务C准备结束-3
2020-08-13 10:20:32.029331+0800 CZProjectTestDemo[7511:1250553] 任务C已经结束-3
2020-08-13 10:20:32.029353+0800 CZProjectTestDemo[7511:1250557] 所有任务全部完成
注意这里任务ABC的延迟操作我设置的是1、2、3秒。如果更改秒数,则任务执行是无顺序的。
网友评论