本文介绍了通过DispatchGroup与DispatchQueue访问主队列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我在后台线程上运行的类中使用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 { }
。
为什么这些不同?
推荐答案
当您调用notify(queue:)
时,dispatchGroup
是否为空(即没有正在运行的块)?如果不是,则为documentation状态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")
}
在本例中,all set
将仅在使用group.leave()
执行两次回调后打印。
另一方面,DispatchQueue.main.async()
会立即将块提交到目标队列,但不一定会在那之后立即启动--例如,可能正在运行带有.barrier
标志的async
块。
更新:使用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")
}
这篇关于通过DispatchGroup与DispatchQueue访问主队列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!