GCD的group方法只有async(异步方法)即
void dispatch_group_async(dispatch_group_t group,
dispatch_queue_t queue,
dispatch_block_t block);
使用group要传2个参数 group、queue,其中group使用
//创建group
dispatch_group_t group = dispatch_group_create();
queue我们可以使用以下几种方式
dispatch_queue_t queue = dispatch_get_main_queue()
//或者
queue = dispatch_get_global_queue(0, 0);
//或者 并行队列
queue = dispatch_queue_create("com.sccc", DISPATCH_QUEUE_CONCURRENT);
//或者串行队列
queue = dispatch_queue_create("com.sccc", DISPATCH_QUEUE_SERIAL);
这里主要区分串行和并行的方式
- (void)doSomething:(void (^)())handler {
if (handler) {
sleep(2);
handler();
}
}
//异步串行group
- (void)groupAsyncSerialTest {
//创建串行队列
dispatch_queue_t queue = dispatch_queue_create("com.sccc", DISPATCH_QUEUE_SERIAL);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
[self doSomething:^() {
NSLog(@"任务一");
}];
});
dispatch_group_async(group, queue, ^{
[self doSomething:^() {
NSLog(@"任务二");
}];
});
dispatch_group_async(group, queue, ^{
[self doSomething:^() {
NSLog(@"任务三");
}];
});
dispatch_group_notify(group, queue, ^{
NSLog(@"前面的任务已完成");
});
}
结果
串行队列打印结果
值得注意的是按照顺序每2s打印一次
串行队列的情况如下:
//异步并行
- (void)groupAsyncConcurrentTest {
//创建并行队列
dispatch_queue_t queue = dispatch_queue_create("com.sccc", DISPATCH_QUEUE_CONCURRENT);
queue = dispatch_get_global_queue(0, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
[self doSomething:^() {
NSLog(@"任务一");
}];
});
dispatch_group_async(group, queue, ^{
[self doSomething:^() {
NSLog(@"任务二");
}];
});
dispatch_group_async(group, queue, ^{
[self doSomething:^() {
NSLog(@"任务三");
}];
});
dispatch_group_notify(group, queue, ^{
NSLog(@"前面的任务已完成");
});
}
结果如下
并行打印结果多次试验总结的结果是任务完成先后顺序不定,前面的任务都完成后才会执行notify中的任务
当然以上的情况不适用于网络请求
网络请求使用group时需要注意
dispatch_group_enter(group);
dispatch_group_leave(group);
搭配使用
下面是没有搭配使用的情况
//异步并行
- (void)groupAsyncConcurrentTest {
//创建并行队列
dispatch_queue_t queue = dispatch_queue_create("com.sccc", DISPATCH_QUEUE_CONCURRENT);
queue = dispatch_get_global_queue(0, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
[[CMAppRequest sharedInstance] guideMessage:^() {
NSLog(@"任务一");
}];
});
dispatch_group_async(group, queue, ^{
[[CMAppRequest sharedInstance] guideMessage:^() {
NSLog(@"任务二");
}];
});
dispatch_group_async(group, queue, ^{
[[CMAppRequest sharedInstance] guideMessage:^() {
NSLog(@"任务三");
}];
});
dispatch_group_notify(group, queue, ^{
NSLog(@"前面的任务已完成");
});
}
结果如下
网络请求打印结果
你会发现notify不起作用了,这时候就要用到enter、leave了
修改代码如下:
//异步并行
- (void)groupAsyncConcurrentTest {
//创建并行队列
dispatch_queue_t queue = dispatch_queue_create("com.sccc", DISPATCH_QUEUE_CONCURRENT);
queue = dispatch_get_global_queue(0, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
[[CMAppRequest sharedInstance] guideMessage:^() {
dispatch_group_leave(group);
NSLog(@"任务一");
}];
dispatch_group_enter(group);
[[CMAppRequest sharedInstance] guideMessage:^() {
dispatch_group_leave(group);
NSLog(@"任务二");
}];
dispatch_group_enter(group);
[[CMAppRequest sharedInstance] guideMessage:^() {
dispatch_group_leave(group);
NSLog(@"任务三");
}];
dispatch_group_notify(group, queue, ^{
NSLog(@"前面的任务已完成");
});
}
//考虑到请求是异步队列,不在需要使用dispatch_group_async
结果如下:
这就正常了,网络请求的就不在做串行和并行的测试了,以上网络请求部分使用的是串行队列,串行的打印结果只和网络请求的返回顺序有关。
- 最后特别需要注意,enter和leave一定要成对出现;否则如实enter多了,notify里的任务就会永远执行不了,若是levae多了则会照成crash
当然这只是group的一部分还有dispatch_group_wait等功能没有一一实现,以上内容只代表个人观点,如有问题欢迎指正,谢谢~~
网友评论