GCD学习之group

2017-04-20  本文已影响13人  浮生若梦的简书

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

结果如下:


这就正常了,网络请求的就不在做串行和并行的测试了,以上网络请求部分使用的是串行队列,串行的打印结果只和网络请求的返回顺序有关。

当然这只是group的一部分还有dispatch_group_wait等功能没有一一实现,以上内容只代表个人观点,如有问题欢迎指正,谢谢~~

上一篇 下一篇

猜你喜欢

热点阅读