如果我的调度组从未完成,会发生什么情况



我有许多异步任务需要全部完成才能继续,所以我正在使用调度组。但是,我能够判断其中一个任务是否提前失败,我通常会调用完成处理程序。

如果我通过调用完成处理程序离开函数的范围,调度组会发生什么情况?

内存是否永久分配?如果最终调用了足够多的 leave(可能是由于错误(,是否有可能仍然可以调用通知块?

例:

func example(completion: @escaping (Bool) - Void) {
let group = DispatchGroup()
group.enter()
asyncFunction1 {
if result == false {
completion(false)
} else {
group.leave()
}
}
group.enter()
asyncFunction2 { result in
if result == true {
group.leave()
}
}
group.notify(queue: .main) {
completion(true)
}
}

在上面的例子中,我有两个异步函数。第一个函数可能会调用completion(false),第二个函数只在成功时调用leave。虽然它可能不是最好的代码示例,但这些条件是可能的。通知块会发生什么情况?

来自 GCD 上的 swift 源代码: https://github.com/apple/swift-corelibs-libdispatch/blob/master/src/semaphore.c

似乎该块将被分配并且永远不会释放。这意味着,块保留的内存也将永远不会被释放。

每当代码块进入调度组以及代码块离开组时,都必须通知调度组。

这意味着,无论函数成功与否,都必须调用dispatchGroup.leave()

当所有块都完成后,调度组会收到通知。

我想知道当休假从未被召唤时会发生什么。仅仅因为它必须被调用,并不意味着它总是会被调用。

好吧,不要"永远不要打电话"它。您必须排列代码,以便每个可能的退出路径都调用leave。如果不能,请不要使用调度组。

如有必要,可以将调度组本身传递到完成处理程序中,以便它可以为您调用leave。但是无论如何,打电话给leave.

最新更新