【问题标题】:Accessing main queue via DispatchGroup vs. DispatchQueue通过 DispatchGroup 与 DispatchQueue 访问主队列
【发布时间】:2018-03-14 20:20:07
【问题描述】:

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

为什么这些不一样?

【问题讨论】:

    标签: ios swift grand-central-dispatch


    【解决方案1】:

    在您调用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")
    }
    

    【讨论】:

    • 谢谢你这么详细的解释!这让我远离了。
    猜你喜欢
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-02
    • 2023-03-04
    • 2018-01-05
    • 1970-01-01
    • 2021-04-26
    相关资源
    最近更新 更多