繁体   English   中英

通过DispatchGroup与DispatchQueue访问主队列

[英]Accessing main queue via DispatchGroup vs. 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是否为空(即没有正在运行的块)? 如果没有,则如文档所述,为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")
}

在此示例中,只有在执行了两个具有group.leave()回调之后,才会打印all set

另一方面, 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")
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM