通过DispatchGroup和DispatchQueue访问主队列

时间:2018-03-14 20:20:07

标签: ios swift grand-central-dispatch

我在一个在后台线程上运行的类中使用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 { }

为什么这些不一样?

1 个答案:

答案 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