为啥我们需要调用主线程进行 UI 更新?

Posted

技术标签:

【中文标题】为啥我们需要调用主线程进行 UI 更新?【英文标题】:Why do we need to call the Main Thread for UI updates?为什么我们需要调用主线程进行 UI 更新? 【发布时间】:2018-12-13 08:21:42 【问题描述】:

我知道我们在更新 UI 时必须调用主线程。 但我无法解释我的队友为什么我们必须这样做,以及为什么 Swift 不自动这样做。

他们曾经这样调用 self.present():

self.present(alert, animated: true)

但我知道你应该这样称呼它:

DispatchQueue.main.async 
      self.present(alert, animated: true)

我实际上想确保始终在主线程上调用该方法,但我不知道如何...另一个问题是:为什么我必须确保在主线程上调用此方法并且不是斯威夫特?当有人调用此方法时,总会有 UI 更新。

@available(ios 5.0, *)
open func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil)

【问题讨论】:

But I know you should call it this way 不,你不应该。仅当当前线程是后台线程时,您才应该这样做。如果真的有这个问题,我无法理解。 要回答为什么,请查看:***.com/questions/31820336/… 【参考方案1】:

在(几乎?)每个 UI 框架中都有一个 UI 线程,所有 UI 操作都必须在其中执行。我认为这种设计的主要原因是防止意外的 UI 行为。考虑以下情况:

表中有一个条目列表,称它们为“A”和“B” 当前选择了“A” 用户想要删除“B” 用户选择“B” 用户按下“删除所选条目”按钮

如果用户使用快速点击器/点击器,并且 UI 是多线程的,则可能会发生“选择 B”事件处理程序在“删除选定条目”处理程序之后执行。因此,“A”仍然被选中并将被删除。

因此,典型的框架会跟踪队列中的事件并以严格的顺序处理此队列。这就是你所说的“单线程”。

因此,如果你在主线程中 dispatch 一些东西,你应该知道执行时间是不确定的,所以你不能依赖入队时的任何 UI 状态。

【讨论】:

以上是关于为啥我们需要调用主线程进行 UI 更新?的主要内容,如果未能解决你的问题,请参考以下文章

为啥loop之后就可以子线程更新ui

iOS子线程操作UI

QT中UI主窗口如何与子线程相互传递参数

即使从主线程调用更新,UI 也不会更新

如何追踪阻塞主(UI)线程的调用?

Android 线程交互