Dispatch.main.async如何"更新UI"?

Mik*_*ike 0 grand-central-dispatch firebase swift

我一直在使用Swift一段时间,而GCD仍然让我感到困惑.

我读了:

https://www.raywenderlich.com/60749/grand-central-dispatch-in-depth-part-1

以及关于发送的Apple文档:

https://developer.apple.com/documentation/dispatch

我理解GCD允许在不同线程上运行多个任务的整体概念(我认为是正确的).

我不太明白的是Dispatch.main.async"更新UI".

例如,如果我在某处调用api并返回数据 - 比如返回所有数据需要5秒钟,那么如何使用Dispatch.main.async帮助更新UI?如何Dispatch.main.async知道要更新的UI?

而且我仍然不能完全取代GCD,为什么不能在加载所有数据时使用某种观察者或委托或闭包?

如果我正在进行api调用但不立即使用数据,请重新:用GCD"更新UI".只是将数据存储在一个数组中,直到我决定使用它,那么是否需要使用Dispatch.main.async

我现在一直在使用firebase/firestore作为数据库.Firebase拥有自己的侦听器并以异步方式运行.我仍然无法得到一个很好的答案:在iOS/Swift中处理来自firebase的异步返回的最佳方法.例如,当我的应用程序加载,如果我去firebase获取数据来填充tableviewcontroller,什么是知道所有数据何时返回的最佳方式?我一直在使用代表,但想知道是否以及如何Dispatch.main.async使用.

Cod*_*odo 6

Dispatch.main.async更新UI.故事的方向不同:如果要更新 UI,则必须从线程执行此操作.如果你当前的代码没有在主线程上Dispatch.main.async运行,那么在线程上运行一些代码是最方便的方法.

这是影响大多数操作系统的旧限制:UI相关操作(如更改UI中的元素)只能从特定线程调用,通常是所谓的线程.

在许多情况下,这不是问题,因为您的UI相关代码通常在某些UI事件(用户点击或点击,按下按键等)触发时起作用.这些事件回调发生在主线程上.所以没有线程问题.

使用GCD,您可以在不同的线程上运行长时间运行的任务,这样任务就不会减慢甚至阻止UI.因此,当这些任务完成并且您想要更新UI(例如显示结果)时,您必须在主线程上执行此操作.有了Dispatch.main.async你可以问GCD主线程上运行的代码.GCD不了解UI.您的代码必须知道要更新的内容.GCD只需在所需的线程上运行您的代码.

如果在任务结束时没有任何内容可以在UI中显示或以其他方式更新,那么您无需致电Dispatch.main.async.

更新Firebase

在火力地堡数据库客户端执行单独的背景所有的网络和磁盘操作线程关闭主线程.

Firebase数据库客户端调用主线程代码的所有回调.

因此无需调用Dispatch.main.asyncFirebase回调.你已经在主线程上了.