在共享汽车项目中,我们遇到这样一个需求。
向服务端获得密钥A,从硬件这边获得密钥B,将AB进行组合加密之后,在进行其他操作。
转换一下就是:任务A、任务B、任务C任务,C需要等到任务A和任务B都完成后才执行。【任务A和任务B执行没有先后顺序】
在串行队列中,可以把该操作放到最后一个任务执行完成后继续,但是在并行队列中怎么做呢。这就有dispatch_group 成组操作。
我们可以使用 dispatch group 来解决这个问题。
【一】初始化一个dispatch group
1.0 创建队列组dispatch group
dispatch_group_t group = dispatch_group_create();
2.0 创建一个全局并发队列
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
【二】向dispatch group中添加任务
【第一种方法】是在这个dispatch group中添加你的代码块,然后这些代码块会运行在你指定的queue中.
dispatch_group_async(group, queue, ^{
// 添加任务A到group
});

不足:如果是非耗时操作,我们可以使用这种方式。但是我们请求web服务需要的是可以马上返回,然后每个请求中都有自己的completion block.这样,dispatch group会认为我们的请求是'马上完成'的。这不是我们想要的,所以我们需要采用其他方法。
【第二种方法】是手动告诉dispatch group你要开始某个任务了.完成任务之后,你也需要手动退出dispath group.
通过dispatch_group_enter(),dispatch_group_leave()两个方法可以实现进入,退出两个动作:
dispatch_group_enter:通知group,下面的任务马上要放到group中执行了。
dispatch_group_leave:通知group,任务完成了,该任务要从group中移除了。
dispatch_group_enter(serviceGroup);
[configService startWithCompletion:^(ConfigResponse *results,NSError* error){
// Do something with the error or results
dispatch_group_leave(serviceGroup);
}];


上面的 Log1 和Log1输出顺序不定,因为是在并发队列上执行,当并发队列全部执行完成后,最后到main队列上执行一个操作,保证“end”是最后输出。
每个enter都必须有相应的leave,否则,你的dispatch group永远不会结束。
在你要去请求一个web service的时候,你先enter dispatch group,然后在返回的completion block中 leave.
【三】dispatch group完成方式
有两种方式.
第一种是阻塞当前的线程,直到dispatch group中的所有任务完成才会返回.
dispatch_group_wait(serviceGroup,DISPATCH_TIME_FOREVER);// Won't get here until everything has finished
第二种不会阻塞当前线程,马上返回.
dispatch_group_notify(serviceGroup,dispatch_get_main_queue(),^{// Won't get here until everything has finished});
在这里我们会使用第二种方法。
网友评论