ios - 将完成处理程序池在一起,以便在执行多个闭包后方法完成

标签 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()
    }
}

我可以轻松地将处理程序链接在一起,但任务可能会花费更长的时间,并且代码会很糟糕。

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

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

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

我希望有一些我所缺少的更好的东西。

最佳答案

只是为了了解 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 都与异步完成处理程序末尾的 leave 相匹配,并且只有当所有匹配都已实际执行时,我们才会继续执行 通知完成处理程序。

关于ios - 将完成处理程序池在一起,以便在执行多个闭包后方法完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44081539/

相关文章:

ios - 创建可触摸的 React-Native-Art 对象?

ios - 将节点设置为从一系列点随机生成并以逐渐加快的速度下降

ios - CALayer 在变换动画后调整回原始大小

Realm SyncUser.authenticate 使用 Google 的 clientID 和 Facebook 失败

iOS TableView

ios - 如何防止物体 swift 离开屏幕?

android - 后台发短信到自己的手机号,短信列表不显示已发短信

ios - 取消 UNNotificationRequest

ios - 如何识别点击整个振荡 subview 以执行交互式动画

ios - Xcode 8 图像补全