dispatch_group的作用:创建一个任务组,然后异步执行加入group的每个任务。比如如果用group管理3个任务的执行,那么这3个任务的执行顺序会同时执行。
dispatch_enter的作用:创建好任务组后,执行加入任务组的操作代码。dispatch_enter和dispatch_leave要成对出现,否则奔溃。
//1.创建任务组
dispatch_group_t group = dispatch_group_create();
//2.加入第一个任务
dispatch_group_enter(group);
BlockView *blockView = [[BlockView alloc] init];
//设置block10秒后回调
[blockView returnTextFieldWithBlock:^(NSString *text) {
NSLog(@"任务组1完成");
/*
在这里我们设置的dispatch_group_wait时间是5秒,但是我们这个任务的回调时间是10秒。所以结果是5秒过后wait超时,程序继续往下执行,打印:wait时间已经到了。然而这个任务还在线程里执行,一直到执行dispatch_group_leave这个任务才完成。
*/
dispatch_group_leave(group);
}];
//3.加入第二个任务
dispatch_group_enter(group);
/*
这里我发现一个问题,我设置的dispatch_after的延时时间是3秒,也就是3秒后把block中的任务加入线程。所以是在dispatch_group_wait时间内就能完成的,但是打印的顺序却是先打印:wait时间已经到了,然后打印:任务组2完成,
*/
dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, 3*NSEC_PER_SEC);
dispatch_after(tt, dispatch_get_main_queue(), ^{
NSLog(@"任务组2完成");
dispatch_group_leave(group);
});
//4.加入第三个任务
dispatch_group_enter(group);
NSLog(@"任务组3完成");
dispatch_group_leave(group);
//5.执行到这句代码后会等待5秒,等待关联的任务组group里的所有任务完成。如果在5秒内都完成了,返回0并继续执行;如果超时未完成,放回非0并继续执行。所以任务组里的任务无论是否全部完成,都会继续执行。
dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5*NSEC_PER_SEC)));
NSLog(@"wait时间已经到了");
//6.notify会简体关联的任务组group中的所有任务是否都已完成(dispatch_group_enter和dispatch_group_leave匹配),完成了就会执行block
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"所有任务组都完成了");
});
在这里,dispatch_group_wait设置超时时间,如果任务组group里的任务在超时时间内完成,就直接继续执行;而超时未完成,那么时限到后还是会继续执行!那么dispatch_group_wait的作用是什么呢?
一个任务是否完成,就看dispatch_group_enter和dispatch_group_leave是否成对出现。如果任务组里加入的所有任务都都成对出现了enter和leave,那么任务组就完成。所以dispatch_group_wait的作用相当于是对子线程的阻塞式延时,延时的最大时间就是超时时间。
比如下面的代码:设置dispatch_group_wait超时时间为5秒,如果5秒内block回调,则返回isOK=YES,否则返回isOK=NO;
- (BOOL)doDispathcGroup{
__block BOOL isOK = NO;
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
BlockView *blockView = [[BlockView alloc] init];
[blockView returnTextFieldWithBlock:^(NSString *text) {
isOK = YES;
dispatch_group_leave(group);
}];
dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5*NSEC_PER_SEC)));
return isOK;
}
在上面的代码执行的时候我有过一个问题,不是说enter和leave是要成对出现的吗?那么如上面的代码,leave还没出现就return不会导致奔溃吗?答案是不会的,因为任务是在开辟的线程里执行的,线程没有结束,那么group就不会结束,相当于线程还是在等待leave。这个方法域的return不会结束线程。