美文网首页
GCD 队列组 dispatch_group

GCD 队列组 dispatch_group

作者: Geniune | 来源:发表于2018-12-15 10:09 被阅读7次

    dispatch_group的关键函数如下:

    1. dispatch_group_t 队列组对象类
    2. dispatch_group_async 先把任务放到队列中,然后再讲队列放入队列组
    3. dispatch_group_notify 用于获取执行完毕回调
    4. dispatch_wait 回到当前线程继续执行后面的操作(会阻塞当前线程)
    5. dispatch_group_enter 用于标志一个任务追加到group,执行一次,相当于group中未执行完毕任务数+1
    6. dispatch_group_leave 用于标志一个任务离开了group,执行一次,相当于group中未执行完毕任务数-1

    面试题

    想必很多小伙伴面试时都被这样问过:有n个请求(耗时操作)分别异步执行,当这些请求全部执行完了回主线程刷新UI。
    吐槽:对于这么个老掉牙的问题,总被问真的很心烦,正所谓千年不死的老妖怪,万年难改的面试题。

    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       
        NSLog(@"请求1");
    });
    
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSLog(@"请求2");
    });
    
    …
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSLog(@“请求n");
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
       
        NSLog(@"所有请求执行完毕,刷新UI");
    });
    

    思路:

    1. 创建dispatch_group_t 队列组
    2. 将n个耗时操作用dispatch_group_async 函数放入异步队列中
    3. 使用dispatch_group_notify 接收回调,并在主队列中刷新UI

    dispatch_wait 使用

    个人理解为一个计数器,需要配合dispatch_group_enter 和dispatch_group_leave 使用。
    如果当前队列组内有未执行完成的任务,那么他就会一直阻塞着其对应的队列。
    只有未执行完成的任务数变为0时,才会解除阻塞,并执行后面追加到该队列组的其他任务。

    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_group_enter(group);//任务数 +1
    dispatch_async(queue, ^{
        
        NSLog(@"任务1");
        
        dispatch_group_leave(group);//任务数 -1
    });
    
    dispatch_group_enter(group);//任务数 +1
    dispatch_async(queue, ^{
        
        NSLog(@"任务2");
        
        dispatch_group_leave(group);//任务数 -1
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
       
        NSLog(@"所有请求执行完毕,刷新UI");
    });
    
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);//等待上面任务全部完成后,往下继续执行(阻塞当前线程)
    
    dispatch_group_async(group, queue, ^{
       
        NSLog(@"任务3");
    });
    

    任务1 和任务2 异步并行执行,且在他们执行完前阻塞当前queue队列。
    任务1 和任务2 全部执行完毕后,dispatch_group_wait解除阻塞,开始执行任务3。
    所有任务都执行完成后,dispatch_group_notify回调。

    从此也可以看出:这里的dispatch_group_enter、dispatch_group_leave 是组合使用的,其作用同于dispatch_group_async。

    如果本文对你有帮助记得点个喜欢哈

    相关文章

      网友评论

          本文标题:GCD 队列组 dispatch_group

          本文链接:https://www.haomeiwen.com/subject/duvohqtx.html