GCD--同步执行
在实际开发中,我们需要按顺序执行一些异步的任务,我们应该怎么做呢?
答案是:dispatch_group_notify
这里我们使用手动管理block的运行状态
dispatch_group_enter相当于提交了一个任务
dispatch_group_leave相当于完成了一个任务
这里需要强调一点
进入和退出group次数必须匹配 如果少了leave话notify是永远都完成不了的
实例代码如下:
dispatch_group_t serviceGroup = dispatch_group_create();
// Start the first task
dispatch_group_enter(serviceGroup);
[self startTask:5 Block:^(BOOL success) {
dispatch_group_leave(serviceGroup);
}];
// Start the second task
dispatch_group_enter(serviceGroup);
[self startTask:5 Block:^(BOOL success) {
dispatch_group_leave(serviceGroup);
}];
dispatch_group_notify(serviceGroup,dispatch_get_main_queue(),^{
NSLog(@"finish");
});
NSLog(@"next");
-
(void)startTask:(NSInteger)time Block:(someBlock)block
{
for (NSInteger i=0; i<time; i++) {NSLog(@"%ld",i);
}
block(YES);
}
输出结果:
2015-05-16 14:46:31.401 syncTest[26054:9467066] 0
2015-05-16 14:46:31.401 syncTest[26054:9467066] 1
2015-05-16 14:46:31.402 syncTest[26054:9467066] 2
2015-05-16 14:46:31.402 syncTest[26054:9467066] 3
2015-05-16 14:46:31.402 syncTest[26054:9467066] 4
2015-05-16 14:46:31.402 syncTest[26054:9467066] 0
2015-05-16 14:46:31.402 syncTest[26054:9467066] 1
2015-05-16 14:46:31.402 syncTest[26054:9467066] 2
2015-05-16 14:46:31.402 syncTest[26054:9467066] 3
2015-05-16 14:46:31.402 syncTest[26054:9467066] 4
2015-05-16 14:46:31.403 syncTest[26054:9467066] next
2015-05-16 14:46:31.421 syncTest[26054:9467066] finish
这里看出任务是头尾相接得,只有dispatch_group_leave之后下一个任务才会进行。
这里需要注意的是我们在dispatchgetmain_queue()主线程的队列里面执行的,不适合运行长时间的任务,一般使用dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
如果不在乎分组内的任务的顺序,可以使用dispatch_group_async
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t serviceGroup = dispatch_group_create();
// Start the first task
dispatch_group_async(serviceGroup, queue, ^{
[self startTask:5 Block:^(BOOL success) {
}];
});
// Start the second task
dispatch_group_async(serviceGroup, queue, ^{
[self startTask:10 Block:^(BOOL success) {
}];
});
dispatch_group_notify(serviceGroup,queue,^{
NSLog(@"finish");
});
NSLog(@"next");
输出结果:
2015-05-16 14:35:26.978 syncTest[25914:9451334] next
2015-05-16 14:35:26.978 syncTest[25914:9451392] 0
2015-05-16 14:35:26.978 syncTest[25914:9451393] 0
2015-05-16 14:35:26.979 syncTest[25914:9451393] 1
2015-05-16 14:35:26.979 syncTest[25914:9451393] 2
2015-05-16 14:35:26.979 syncTest[25914:9451393] 3
2015-05-16 14:35:26.979 syncTest[25914:9451393] 4
2015-05-16 14:35:26.979 syncTest[25914:9451393] 5
2015-05-16 14:35:26.979 syncTest[25914:9451393] 6
2015-05-16 14:35:26.979 syncTest[25914:9451393] 7
2015-05-16 14:35:26.979 syncTest[25914:9451393] 8
2015-05-16 14:35:26.980 syncTest[25914:9451393] 9
2015-05-16 14:35:26.979 syncTest[25914:9451392] 1
2015-05-16 14:35:26.980 syncTest[25914:9451392] 2
2015-05-16 14:35:26.980 syncTest[25914:9451392] 3
2015-05-16 14:35:26.980 syncTest[25914:9451392] 4
2015-05-16 14:35:26.980 syncTest[25914:9451392] finish
这里任务1和任务2的调用虽然是按照队列来的,但是因为是block,所以执行的同时的,而全部完成之后才会调用完成方法,对于整个group来说是异步的,一旦运行之后,next的被调用时间是不确定的。