当更新我的 UI 以响应异步操作时,我应该在哪里调用 DispatchQueue?

When updating my UI in response to an async action, where should I call DispatchQueue?

在我的 iOS 应用程序中,我发出了很多网络请求。当这些请求成功/失败时,将触发视图控制器中的委托方法。委托方法包含负责更新 UI 的代码。在以下示例中,didUpdate(foo:) 是委托方法,presentAlert(text:) 是我的 UI 更新。

没有DispatchQueue,代码会像这样:

func didUpdate(foo: Foo) {
  self.presentAlert(text: foo.text)
}

func presentAlert(text: String) {
  let alertController = ...

  self.present(alertController, animated: true)
}

当谈到使用 DispatchQueue 来确保我的 UI 将快速更新时,我开始失去判断代码中实际发生的事情的能力。下面两种实现方式有区别吗?

第一种方式:

func didUpdate(foo: Foo) {
  self.presentAlert(text: foo.text)
}

func presentAlert(text: String) {
  let alertController = ...

  DispatchQueue.main.async {
    self.present(alertController, animated: true)
  }
}

第二种方式:

func didUpdate(foo: Foo) {
  DispatchQueue.main.async {
    self.presentAlert(text: foo.text)
  }
}

func presentAlert(text: String) {
  let alertController = ...

  self.present(alertController, animated: true)
}

Does it matter which approach I go with? It seems like having the DispatchQueue block inside of the presentAlert function is better, so I don't have to include DispatchQueue.main.async any time I want to call presentAlert?

这两种方法没有区别。但是,正如您所说,第二种方法的缺点是您必须将对 presentAlert 的所有调用都包装在 DispatchQueue.main.async 闭包周围。

Is it only necessary to explicitly send a block to the main queue when you (or a framework you are using) has "moved" yourself into a background queue?

如果你这里的问题是从主队列调度到主队列会不会有问题,那么答案是否定的。如果您从主队列中异步调度主队列,它所做的就是稍后在 运行 循环中调用您的方法。

If there are any external resources that may help my understanding of GCD, please let me know!

互联网上有很多资源可以更好地理解 GCD。看看这个 Raywenderlich tutorial。这是一个很好的起点。

我的建议是,如果您有一个中央 class 来处理所有 Web 服务调用,那么在获取网络服务响应。这样,您就不必在视图或 viewcontroller classes.

中继续调度到主队列