dispatch_group_t 日常使用注意事项

一、背景简介
平时在进行多线程处理任务时,有时候希望多个任务之间存在着一种联系,希望在所有的任务执行完后做一些总结性处理。
那么就可以将多个任务放在一个任务组中进行统一管理。dispatch提供了相应的API供我们完成这一需求。

二、dispatch_group_t相关属性介绍
1.dispatch_group_async(group, queue, block);
将block任务添加到queue队列,并被group组管理
2.dispatch_group_enter(group);
声明dispatch_group_enter(group)下面的任务由group组管理,group组的任务数+1
3.dispatch_group_leave(group);
相应的任务执行完成,group组的任务数-1
4.dispatch_group_create();
创建一个group组
5.dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);
当前线程暂停,等待dispatch_group_wait(group1, DISPATCH_TIME_FOREVER)上面的任务执行完成后,线程才继续执行。
6.dispatch_group_notify(group1, queue1,block);
监听group组中任务的完成状态,当所有的任务都执行完成后,触发block块,执行总结性处理。

三、常见用法的区别
在使用group组处理任务时,常见的有两种组合。
其一:

dispatch_group_async(group, queue, block);

dispatch_group_notify(group1, queue1, block);

在这种组合下,根据任务是同步、异步又分为两种,这两种组合的执行代码与运行结果如下:

第一种:同步任务时

  dispatch_queue_t queue1 = dispatch_queue_create("dispatchGroupMethod1.queue1", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group1 = dispatch_group_create();
    
    dispatch_group_async(group1, queue1, ^{
        dispatch_sync(queue1, ^{
            for (NSInteger i =0; i<3; i++) {
                sleep(1);
                NSLog(@"%@-同步任务执行-:%ld",@"任务1",(long)i);

            }
        });
    });
    
    
    dispatch_group_async(group1, queue1, ^{
        dispatch_sync(queue1, ^{
            for (NSInteger i =0; i<3; i++) {
                sleep(1);
                NSLog(@"%@-同步任务执行-:%ld",@"任务2",(long)i);
                
            }
        });
    });
    
//    //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
//    dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);
    
    //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
    dispatch_group_notify(group1, queue1, ^{
        NSLog(@"Method1-全部任务执行完成");
    });

同步任务运行结果:

2017-04-22 14:28:05.883 MyTestWorkProduct[27793:158785] 任务1-同步任务执行-:0
2017-04-22 14:28:05.884 MyTestWorkProduct[27793:159210] 任务1-同步任务执行-:0
2017-04-22 14:28:06.885 MyTestWorkProduct[27793:159210] 任务1-同步任务执行-:1
2017-04-22 14:28:06.885 MyTestWorkProduct[27793:158785] 任务1-同步任务执行-:1
2017-04-22 14:28:07.886 MyTestWorkProduct[27793:158785] 任务1-同步任务执行-:2
2017-04-22 14:28:07.886 MyTestWorkProduct[27793:159210] 任务1-同步任务执行-:2
2017-04-22 14:28:07.886 MyTestWorkProduct[27793:159186] Method1-全部任务执行完成

第二种:异步任务时

 dispatch_queue_t queue1 = dispatch_queue_create("dispatchGroupMethod1.queue1", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group1 = dispatch_group_create();
    
    dispatch_group_async(group1, queue1, ^{
        dispatch_async(queue1, ^{
            for (NSInteger i =0; i<3; i++) {
                sleep(1);
                NSLog(@"%@-异步任务执行-:%ld",@"任务1",(long)i);

            }
        });
    });
    
    
    dispatch_group_async(group1, queue1, ^{
        dispatch_async(queue1, ^{
            for (NSInteger i =0; i<3; i++) {
                sleep(1);
                NSLog(@"%@-异步任务执行-:%ld",@"任务2",(long)i);
                
            }
        });
    });
    
//    //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
//    dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);
    
    //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
    dispatch_group_notify(group1, queue1, ^{
        NSLog(@"Method1-全部任务执行完成");
    });

异步任务运行结果:

2017-04-22 14:12:28.889 MyTestWorkProduct[27424:147249] Method1-全部任务执行完成
2017-04-22 14:12:29.893 MyTestWorkProduct[27424:147231] 任务2-异步任务执行-:0
2017-04-22 14:12:29.893 MyTestWorkProduct[27424:146850] 任务1-异步任务执行-:0
2017-04-22 14:12:30.896 MyTestWorkProduct[27424:147231] 任务2-异步任务执行-:1
2017-04-22 14:12:30.896 MyTestWorkProduct[27424:146850] 任务1-异步任务执行-:1
2017-04-22 14:12:31.901 MyTestWorkProduct[27424:147231] 任务2-异步任务执行-:2
2017-04-22 14:12:31.901 MyTestWorkProduct[27424:146850] 任务1-异步任务执行-:2

结论:dispatch_group_async(group, queue, block) 和 dispatch_group_notify(group1, queue1, block) 组合在执行同步任务时正常,在执行异步任务时不正常。

 

其二

dispatch_group_enter(group);

dispatch_group_leave(group);

 dispatch_group_notify(group1, queue1,block);

在这种组合下,根据任务是同步、异步又分为两种,这两种组合的执行代码与运行结果如下:

第一种:同步任务时

 dispatch_queue_t queue2 = dispatch_queue_create("dispatchGroupMethod2.queue2", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group2 = dispatch_group_create();
    

    dispatch_group_enter(group2);
    dispatch_sync(queue2, ^{
        for (NSInteger i =0; i<3; i++) {
            sleep(1);
            NSLog(@"%@-同步任务执行-:%ld",@"任务1",(long)i);
            
        }
        dispatch_group_leave(group2);
    });
    

    
    dispatch_group_enter(group2);
    dispatch_sync(queue2, ^{
        for (NSInteger i =0; i<3; i++) {
            sleep(1);
            NSLog(@"%@-同步任务执行-:%ld",@"任务2",(long)i);
            
        }
        dispatch_group_leave(group2);
    });
    
//    //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
//    dispatch_group_wait(group2, DISPATCH_TIME_FOREVER);
    
    //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
    dispatch_group_notify(group2, queue2, ^{
        NSLog(@"Method2-全部任务执行完成");
    });

同步任务执行结果:

2017-04-22 14:28:05.884 MyTestWorkProduct[27793:159186] 任务2-同步任务执行-:0
2017-04-22 14:28:06.885 MyTestWorkProduct[27793:159186] 任务2-同步任务执行-:1
2017-04-22 14:28:07.886 MyTestWorkProduct[27793:159186] 任务2-同步任务执行-:2
2017-04-22 14:28:08.887 MyTestWorkProduct[27793:158785] 任务2-同步任务执行-:0
2017-04-22 14:28:09.888 MyTestWorkProduct[27793:158785] 任务2-同步任务执行-:1
2017-04-22 14:28:10.889 MyTestWorkProduct[27793:158785] 任务2-同步任务执行-:2
2017-04-22 14:28:10.889 MyTestWorkProduct[27793:159830] Method2-全部任务执行完成

 

第二种:异步任务时

   dispatch_queue_t queue2 = dispatch_queue_create("dispatchGroupMethod2.queue2", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group2 = dispatch_group_create();
    

    dispatch_group_enter(group2);
    dispatch_async(queue2, ^{
        for (NSInteger i =0; i<3; i++) {
            sleep(1);
            NSLog(@"%@-异步任务执行-:%ld",@"任务1",(long)i);
            
        }
        dispatch_group_leave(group2);
    });
    

    
    dispatch_group_enter(group2);
    dispatch_async(queue2, ^{
        for (NSInteger i =0; i<3; i++) {
            sleep(1);
            NSLog(@"%@-异步任务执行-:%ld",@"任务2",(long)i);
            
        }
        dispatch_group_leave(group2);
    });
    
//    //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
//    dispatch_group_wait(group2, DISPATCH_TIME_FOREVER);
    
    //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
    dispatch_group_notify(group2, queue2, ^{
        NSLog(@"Method2-全部任务执行完成");
    });

异步任务执行结果:

2017-04-22 14:16:38.705 MyTestWorkProduct[27518:149631] 任务1-异步任务执行-:0
2017-04-22 14:16:38.705 MyTestWorkProduct[27518:149624] 任务2-异步任务执行-:0
2017-04-22 14:16:39.709 MyTestWorkProduct[27518:149631] 任务1-异步任务执行-:1
2017-04-22 14:16:39.709 MyTestWorkProduct[27518:149624] 任务2-异步任务执行-:1
2017-04-22 14:16:40.712 MyTestWorkProduct[27518:149624] 任务2-异步任务执行-:2
2017-04-22 14:16:40.712 MyTestWorkProduct[27518:149631] 任务1-异步任务执行-:2
2017-04-22 14:16:40.713 MyTestWorkProduct[27518:149631] Method2-全部任务执行完成

结论:

dispatch_group_enter(group)、dispatch_group_leave(group) 和  dispatch_group_notify(group1, queue1,block) 组合在执行同步任务时正常,在执行异步任务时正常。

 

posted @ 2017-04-22 15:14  滴水微澜  阅读(8908)  评论(0编辑  收藏  举报