我在一个在后台线程上运行的类中使用DispatchGroup。有时,我需要更新UI,因此我调用以下代码:
dispatchGroup.notify(queue: .main) {
self.delegate?.moveTo(sender: self, location: location)
self.delegate?.updateLabel(sender: self, item: self.currentItem)
}
不幸的是,没有任何反应。但是,如果我通过DispatchQueue.main.async { }
调用相同的代码,就像这样:
DispatchQueue.main.async {
self.delegate?.moveTo(sender: self, location: location)
self.delegate?.updateLabel(sender: self, item: self.currentItem)
}
...委托来电已经完成。我的印象是dispatchGroup.notify(queue: .main) { }
相当于DispatchQueue.main.async { }
。
为什么这些不一样?
答案 0 :(得分:3)
当您拨打dispatchGroup
时,notify(queue:)
是否为空(即没有阻止正在运行)?如果没有,则documentation说明dispatchGroup.notify(queue:)
当一组先前提交的块对象完成时,计划要提交到队列的工作项。
这意味着只有在最后一次leave()
调用后,当组变空时,才会执行闭包。当然,enter()
和leave()
必须平衡。
考虑以下示例:
let group = DispatchGroup()
group.enter()
someLongRunningTask() {
// completion callback
group.leave()
}
group.enter()
anotherLongRunningTask() {
// completion callback
group.leave()
}
group.notify(queue: .main) {
print("all set")
}
在此示例中,只有在all set
执行两次回调后才会打印group.leave()
。
另一方面,DispatchQueue.main.async()
立即将块提交到目标队列,但它不一定会在此之后开始 - 例如,async
块可能会运行{{1}国旗。
更新:使用.barrier
执行上述示例(希望它能说清楚):
DispatchQueue