将完成处理程序汇集在一起​​,一旦多次closures执行,方法就完成了

我有一个场景,我想要并行执行三个不同的asynchronous任务。 一旦完成了这三项任务,我就想让调用方法知道这一点,并调用它自己的完成处理程序。

下面是这个逻辑的一个非常简化的版本:

class ViewController: UIViewController { func doTasks(with object: Object, completionHandler: () -> Void) { // Once A, B & C are done, then perform a task wrapupTask() // When task is complete, call completionHandler completionHandler() } } fileprivate extension ViewController { func taskA(with object: Object, completionHandler: () -> Void) { // Do something completionHandler() } func taskB(with object: Object, completionHandler: () -> Void) { // Do something completionHandler() } func taskC(with object: Object, completionHandler: () -> Void) { // Do something completionHandler() } } 

我可以轻松地将处理程序链接在一起,但是这个任务可能需要更长的时间,代码会很糟糕。

我考虑的另一个项目是一个简单的计数器,每次完成一个任务时递增,然后一旦它达到3,就会通过如下的方式调用wrapupTask():

 var count: Int { didSet { if count == 3 { wrapupTask() } } } 

我考虑过的另一个选项是创build一个操作队列,然后将任务加载到该队列中,并依赖于何时运行我的包装任务。 一旦队列为空,它将调用完成处理程序。 不过,这似乎比我更愿意为我想要完成的工作做更多的工作。

我希望有更好的东西,我只是想念。

只要拿起OOPer说的话,你正在寻找DispatchGroup。 在下文中,对taskAtaskBtaskC是伪代码,但其他一切都是真实的:

 func doTasks(with object: Object, completionHandler: () -> Void) { let group = DispatchGroup() group.enter() taskA() { // completion handler group.leave() } group.enter() taskB() { // completion handler group.leave() } group.enter() taskC() { // completion handler group.leave() } group.notify(queue: DispatchQueue.main) { // this won't happen until all three tasks have finished their completion handlers completionHandler() } } 

每个enter都与asynchronous完成处理程序结束时的假相匹配,只有当所有匹配实际执行完毕,我们才能继续执行notify完成处理程序。