GCD 队列组 dispatch_group

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)