Adr*_*ian 4 grand-central-dispatch ios swift
我在后台线程上运行的类中使用 DispatchGroup。偶尔需要更新UI,所以调用如下代码:
dispatchGroup.notify(queue: .main) {
self.delegate?.moveTo(sender: self, location: location)
self.delegate?.updateLabel(sender: self, item: self.currentItem)
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,什么也没有发生。但是,如果我调用相同的代码, via DispatchQueue.main.async { },如下所示:
DispatchQueue.main.async {
self.delegate?.moveTo(sender: self, location: location)
self.delegate?.updateLabel(sender: self, item: self.currentItem)
}
Run Code Online (Sandbox Code Playgroud)
...委托调用完成。我在印象dispatchGroup.notify(queue: .main) { }下相当于DispatchQueue.main.async { }。
为什么这些不一样?
dispatchGroup当你打电话时,你是空的(即没有块在运行)notify(queue:)吗?如果没有,如文档所述dispatchGroup.notify(queue:)
当一组先前提交的块对象完成时,安排要提交到队列的工作项。
这意味着你的闭包只会在最后一次leave()调用之后执行,当组变空时。而且,当然,enter()s 和leave()s 必须平衡。
考虑以下示例:
let group = DispatchGroup()
group.enter()
someLongRunningTask() {
// completion callback
group.leave()
}
group.enter()
anotherLongRunningTask() {
// completion callback
group.leave()
}
group.notify(queue: .main) {
print("all set")
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,all set只有在两次group.leave()执行回调后才会打印。
另一方面,DispatchQueue.main.async()立即将块提交到目标队列,但它不一定会在此之后立即启动 - 例如,可能会运行async带有.barrier标志的块。
更新:使用上述示例的实现DispatchQueue(希望它使事情变得清晰):
let group = DispatchGroup()
group.enter()
someLongRunningTask() {
// completion callback
group.leave()
}
group.enter()
anotherLongRunningTask() {
// completion callback
group.leave()
}
group.wait() // waits synchronously for the submitted work to complete
DispatchQueue.main.async {
print("all set")
}
Run Code Online (Sandbox Code Playgroud)