IOS:dispatch_group_enter的学习

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不会结束线程。


你可能感兴趣的:(IOS:dispatch_group_enter的学习)