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

时间:2018-09-27 21:43:59

标签: ios swift grand-central-dispatch dispatch-queue

在我的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)
}
  • 我采用哪种方法有关系吗?似乎在presentAlert函数中包含DispatchQueue块似乎更好,因此我想调用DispatchQueue.main.async时不必包含presentAlert吗?

  • 仅当您(或使用的框架)将自己“移动”到后台队列中时,才需要将块显式发送到主队列吗?

  • 如果有任何外部资源可以帮助我理解GCD,请告诉我!

1 个答案:

答案 0 :(得分:1)

  

我采用哪种方法有关系吗?似乎在presentAlert函数中包含DispatchQueue块似乎更好,所以我想调用presentAlert时就不必包括DispatchQueue.main.async了。

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

  

仅当您(或使用的框架)将自己“移动”到后台队列中时,才需要将块显式发送到主队列吗?

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

  

如果有任何外部资源可以帮助我理解GCD,请告诉我!

Internet上有许多资料可以更好地了解GCD。看看这个Raywenderlich tutorial。这是一个很好的起点。

我的建议是,如果您有一个处理所有Web服务调用的中央类,则在获取Web服务响应后解析数据后,最好在主队列上调用完成回调闭包。这样,您将不必在您的视图或Viewcontroller类中继续调度到主队列。