GCD使用group进行多线程同步主要有三种方案:
- dispatch_group_notify
- dispatch_group_wait
- dispatch_group_enter和dispatch_group_level
前两种方法属于同一类型使用也比较简单,但是为什么看开源项目的源码时经常看到dispatch_group_enter和dispatch_group_level搭配的使用呢?主要是因为如果在dispatch_group_async里执行的是异步代码,前两种方式会直接触发而不会等待异步任务完成。
像下边这种情况:
- (void)groupSync1
{
dispatch_queue_t dispatchQueue = dispatch_queue_create("test.queue1", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
dispatch_group_t dispatchGroup = dispatch_group_create();
dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
dispatch_async(globalQueue, ^{
sleep(5);
NSLog(@"任务一完成");
});
});
dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
dispatch_async(globalQueue, ^{
sleep(8);
NSLog(@"任务二完成");
});
});
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
NSLog(@"notify:任务都完成了");
});
}
2018-12-17 17:24:27.899327+0800 Test[5022:529754] notify:任务都完成了
2018-12-17 17:24:32.893964+0800 Test[5022:529800] 任务一完成
2018-12-17 17:24:35.894750+0800 Test[5022:529805] 任务二完成
而使用dispatch_group_enter和dispatch_group_level就可以避免这种情况:
- (void)groupSync2
{
dispatch_queue_t dispatchQueue = dispatch_queue_create("test.queue2", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
dispatch_group_t dispatchGroup = dispatch_group_create();
dispatch_group_enter(dispatchGroup);
dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
dispatch_async(globalQueue, ^{
sleep(5);
NSLog(@"任务一完成");
dispatch_group_leave(dispatchGroup);
});
});
dispatch_group_enter(dispatchGroup);
dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
dispatch_async(globalQueue, ^{
sleep(8);
NSLog(@"任务二完成");
dispatch_group_leave(dispatchGroup);
});
});
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
NSLog(@"notify:任务都完成了");
});
}
2018-12-17 17:30:49.793777+0800 Test[5134:547774] 任务一完成
2018-12-17 17:30:52.797544+0800 Test[5134:547775] 任务二完成
2018-12-17 17:30:52.797843+0800 Test[5134:547707] notify:任务都完成了
网友评论