iOS GCD Grop Queue 队列组
2020-02-18 本文已影响0人
CrystalZhu
当遇到需要执行多个线程并发执行,然后等多个线程都结束之后,再汇总执行结果时可以用group queue
- 使用场景: 同时下载多个图片,所有图片下载完成之后去更新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 每秒有多少纳秒
1000USEC_PER_SEC 每秒有多少毫秒
USEC_PER_SEC*NSEC_PER_USEC 每毫秒有多少纳秒