iOS GCD Grop Queue 队列组

2020-02-18  本文已影响0人  CrystalZhu

当遇到需要执行多个线程并发执行,然后等多个线程都结束之后,再汇总执行结果时可以用group queue

  1. 使用场景: 同时下载多个图片,所有图片下载完成之后去更新UI(需要回到主线程)或者去处理其他任务(可以是其他线程队列)
    2.原理: 使用函数 dispatch_group_create 创建dispatch group,然后使用函数dispatch_group_async来将要执行的block任务提交到一个dispatch queue, 同时将他们添加到一个组,等要执行的block任务全部执行完成之后,使用dispatch_group_notify 函数接收完成时的消息
    3.示例:
    Object-C中的使用示例
dispatch_queue_t conCurrentGlobalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_queue_t groupQueue = dispatch_group_create();
NSLog(@"current task");
dispatch_group_enter(groupQueue);
dispatch_group_async(groupQueue, conCurrentQueue, ^{
    //请求1
    [网络请求: {
       成功: dispatch_group_leave(groupQueue);
       失败: dispatch_group_leave(groupQueue);
    }];
  });
  dispatch_group_enter(groupQueue);
  dispatch_group_async(groupQueue, conCurrentGlobalQueue, ^{
     //请求2
    [网络请求: {
       成功: dispatch_group_leave(groupQueue);
       失败: dispatch_group_leave(groupQueue);
    }];
  });
  dispatch_group_notify(groupQueue, ^{
    NSLog(@"groupQueue 中的任务都执行完毕,回到主线程更新UI");
  });
});

swift中的使用示例

let queue1 = DispatchQueue(label: "1")
let queue2 = DispatchQueue(label: "2")
let groupQueue = DispatchGroup()
groupQueue.enter()
queue1.async(group: groupQueue){
  failCallBack = { () -> void in
    groupQueue.leave()
  }
  successCallBack = { () -> void in
    groupQueue.leave()
  }
}
groupQueue.enter()
queue2.async(group: groupQueue){
  failCallBack = { () -> void in
    groupQueue.leave()
  }
  successCallBack = { () -> void in
    groupQueue.leave()
  }
  groupQueue.notify(queue: DispatchQueue.main){
    // 更新UI
  }
}

因为网络请求一般都是异步的,我们并不知道什么时候网络请求结束,所以使用dispatch_group_enter(group) 和 dispatch_group_leave(group) 这种方式更为灵活,enter 和 leave 必须结合使用,有几次enter就要有几次leave,否则group会一直存在,当所有的enter的block都leave以后,会执行dispatch_group_notify的block.
4.在当前线程阻塞的同步等待 dispatch_group_wait

dispatch_group_t groupQueue = dispatch_group_create();
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, 10*NSEC_PER_SEC);
dispatch_group_t conCurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"current task");
dispatch_group_async(groupQueue, conCurrentQueue, ^{
  long isExecuteOver = dispatch_group_wait(groupQueue, delayTime);
  if (isExecuteOver){
    NSLog(@"wait over");
  }else{
    NSLog(@"not over");
  }
  NSLog(@"并行任务1");
});
dispatch_group_async(groupQueue, conCurrentGlobalQueue, ^ {
  NSLog(@"并行任务2");
});

输出:
current task -> 并行任务2 -> wait over -> 并行任务1

dispatch_time(dispatch_time_t when, int64_t delta);

第一个参数:一般是DISPATCH_TIME_NOW, 表示从现在开始
第二个参数:延时的具体问题
延时1秒可以写成:
1NSEC_PER_SEC 每秒有多少纳秒
1000
USEC_PER_SEC 每秒有多少毫秒
USEC_PER_SEC*NSEC_PER_USEC 每毫秒有多少纳秒

上一篇 下一篇

猜你喜欢

热点阅读