将完成处理程序汇集在一起​​,以便在执行多个闭包后方法完成

Cod*_*der 1 ios swift3

我有一个场景,我想并行执行三个不同的异步任务.完成所有三个任务后,我希望调用方法知道这一点并调用它自己的完成处理程序.

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

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我考虑的另一个项目是一个简单的计数器,每次任务完成时递增,然后一旦它达到3,然后通过类似这样的事件调用wrapupTask():

var count: Int {
   didSet {
      if count == 3 {
         wrapupTask()
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

我考虑的另一个选项是创建一个操作队列,然后将任务加载到其中,并依赖于何时运行我的自动换行任务.一旦队列为空,它将调用完成处理程序.然而,这似乎比我想要完成的工作更多的工作.

我希望有一些我失踪的更好的东西.

mat*_*att 6

只是为了了解OOPer所说的内容,您正在寻找DispatchGroup.在下文中,调用taskA,taskB以及taskC是伪代码,但一切是真实的:

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

每个enterleave在异步完成处理程序的末尾匹配a ,并且只有当所有匹配实际执行时,我们才进入notify完成处理程序.