GCD学习之group

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等功能没有一一实现,以上内容只代表个人观点,如有问题欢迎指正,谢谢~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1 GCD 术语 1.1 Serial vs. Concurrent 串行 vs. 并发 概念:该术语描述执行当前...
    NinthDay阅读 3,978评论 2 38
  • 2017-07-28iOS开发 导语:在iOS中,多线程方案有四种:pthread、NSThread、NSOper...
    C9090阅读 409评论 0 1
  • 在这两部分的系列中,第一个部分的将解释 GCD 是做什么的,并从许多基本的 GCD 函数中找出几个来展示。在第二部...
    透支未来阅读 367评论 0 1
  • 学习多线程,转载两篇大神的帖子,留着以后回顾!第一篇:关于iOS多线程,你看我就够了 第二篇:GCD使用经验与技巧...
    John_LS阅读 637评论 0 3
  • 四圣谛:苦集灭道 五蕴 色蕴:包括自身的眼、耳、鼻、舌、身等五根,以及反映自身而起感受作用的色、声、香、味、触的五...
    monchhichi1005阅读 414评论 0 0