GCD任务组

场景

假设有这样一个场景:有3个任务A,B,C,任务B需要在任务A和任务C执行完毕之后才执行,但是我们又想实现异步执行,怎么办呢?这种场景经常出现在异步加载图片的时候,有的时候需要下载多张图片,在多张图片下载完毕之后再执行其他操作。
这个时候就需要GCD中的任务组dispatch_group_t

dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_async(group, queue, ^{
    NSLog(@"任务A");
});
dispatch_group_async(group, queue, ^{
    NSLog(@"任务C");
});
dispatch_group_notify(group, queue, ^{
    NSLog(@"任务B");
});

在使用dispatch_group_create 创建一个任务组之后,就可以向其中中添加任务了,因为我们需要异步操作,所以说参数使用并行队列。
在最后,使用dispatch_group_notify 来表示执行完任务A和任务C之后执行任务B。

问题:发现在使用的过程中,在任务A,任务C里面并不能写网络请求,如果dispatch_group_async里执行的是异步代码dispatch_group_notify会直接触发而不会等待异步任务完成在执行,所以这时候就需要dispatch_group_enterdispatch_group_level

dispatch_group_enter、dispatch_group_level

dispatch_async相比,当我们调用n次dispatch_group_enter后再调用n次dispatch_group_level时,dispatch_group_notify会收到同步信号;这个特点使得它非常适合处理异步任务的同步,当异步任务开始前调用dispatch_group_enter异步任务结束后调用dispatch_group_leve

- (void)groupSync
{
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
       
        sleep(5);
        NSLog(@"任务一完成");
        dispatch_group_leave(group);
    });
    dispatch_group_enter(group);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        sleep(8);
        NSLog(@"任务二完成");
        dispatch_group_leave(group);
    });
    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        
        NSLog(@"任务完成");
    });
}

注意:上面的这个例子,你可以在网络任务开始的时候调用dispatch_group_enter,而在网络任务结果回调的时候调用dispatch_group_leave,这个时候就可以达到预想的效果了。

总结

如果dispatch_group_async里执行的是异步代码dispatch_group_notify会直接触发而不会等待异步任务完成,而dispatch_group_enter、和dispatch_group_leave则不会有这个问题,它们只需要在任务开始前enter结束后leave即可达到线程同步的效果。

你可能感兴趣的:(GCD任务组)