我有一个场景,我希望并行执行三个不同的异步任务。完成所有三个任务后,我希望调用方法知道这一点并调用它自己的完成处理程序。
下面是一个非常简化的逻辑版本:
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()
}
}
}
我考虑的另一个选项是创建一个操作队列,然后将任务加载到其中,并依赖于何时运行我的自动换行任务。一旦队列为空,它将调用完成处理程序。然而,这似乎比我想要完成的工作更多的工作。
我希望有一些更好的东西,我错过了。
答案 0 :(得分: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()
}
}
每个enter
在异步完成处理程序的末尾与leave
匹配,并且只有当所有匹配实际执行时,我们才会继续执行notify
完成处理程序。 / p>