我们是不是需要在主线程或主队列中更新 UI?

Posted

技术标签:

【中文标题】我们是不是需要在主线程或主队列中更新 UI?【英文标题】:Do we need to update UI in main thread or in main queue?我们是否需要在主线程或主队列中更新 UI? 【发布时间】:2018-07-05 10:42:17 【问题描述】:

我阅读了很多文章,其中指定我们需要在主线程中更新 UI,但是每当我更新我的 UI 时始终是代码。

DispatchQueue.main 这反过来给了我队列而不是线程。我将如何访问线程或两者都相同?

【问题讨论】:

始终在主线程上更新 UI。基本上 MainQueue 添加您的代码块以在主线程上执行。 DispatchQueue.main 允许您将队列添加到块中以在主线程上调用它。该块内的代码不会立即被调用,但那是不冻结它被调用的线程。 我担心的是如果我需要更新主线程中的 UI 为什么我正在访问主队列或访问主队列本身正在访问主线程。 队列会将作业添加到线程中? @Tj3n 这间接意味着主队列本身就是主线程?或者我们可以像 ios 编程中那样声明 UI 更新应该在主队列上完成。 【参考方案1】:

想象一个火车站,其中火车的编号与它离开的站台的编号相同。

所以如果你想要#1 火车,你就站在#1 站台上。不先站在月台上就不能上火车。其他想上这列火车的人也都站在月台上等待上车的机会。

火车就是线程。平台就是队列。

如果你想进入主线程,进入主队列。

【讨论】:

我在这个话题上看到的最好的解释之一。 这是一种叫做解释的东西,你太棒了,喜欢它。 “列车号与站台号相同”的类比表明队列和线程之间存在1-1的关系,并不存在。分派到不同(非主)队列的项目可以在同一个线程上执行(甚至在主线程上),分派到同一个队列的不同项目可能在不同的线程上执行。【参考方案2】:

来自并发编程指南中的Dispatch Queues:

主调度队列

主调度队列是一个全局可用的串行队列,它在应用程序的主线程上执行任务。此队列与应用程序的运行循环(如果存在)一起工作,以将排队任务的执行与附加到运行循环的其他事件源的执行交错​​。因为它在应用程序的主线程上运行,所以主队列通常用作应用程序的关键同步点。

一般情况下,GCD维护一个线程池,没有1-1 调度队列和线程之间的关系。但是主队列 很特别:它与主线程绑定,所有项目都被调度 到主队列在主线程上执行。 (同样是 OperationQueue.main 为真。)

发送代码到DispatchQueue.main(或OperationQueue.main) 确保它在主线程上执行,并与 其他 UI 更新。

在这个意义上,术语“在主线程上执行”和 “在主队列上执行”经常互换使用。

【讨论】:

【参考方案3】:

DispatchQueue 管理代码在特定线程上的执行。

来自 Apple 文档:

DispatchQueue 管理工作项的执行。每个工作项 提交到队列的线程池由 系统。

所以,当你打电话时

DispatchQueue.main.async 
        //your code

此代码被提交到main 队列,该队列又在主线程上运行。

【讨论】:

感谢您的链接。但是,如果我做出类似“所有 UI 更新必须在主队列上完成比主线程更有意义,因为应用程序程序员无法访问主队列的主线程”这样的声明。请指导。 主线程和主队列对于这个问题(以及几乎所有用例)是相同的,但它们不是 100% 相同的。此外,您并不总是使用主队列访问主线程,因此更改措辞只会让不同类别的用户感到困惑! 说 UI 更新应该在 Main queue 上完成是不完整的,因为它限制了人们应该只使用 DispatchQueue 来进行 UI 更改的理解。因为还有其他方法可以在主线程上执行代码。 DispatchQueue 就是其中一种方式。 谢谢,@StephenDarlington UditS。你的陈述现在看起来非常合乎逻辑。【参考方案4】:

//主线程

DispatchQueue.main.async
 
 //eg. 
 tableview.reloadData()
  // here you update your UI.

【讨论】:

是的,如果你想更新表格视图的 UI 然后添加 (tableview.relodedata()) 否则你希望。仅此一个示例。 你的意思是reloadData 你链接的方法叫reloadData,而不是relodedata 让我们continue this discussion in chat.

以上是关于我们是不是需要在主线程或主队列中更新 UI?的主要内容,如果未能解决你的问题,请参考以下文章

GCD主队列是不是必须在主线程上执行?

[转]Android限制只能在主线程中进行UI访问的实现原理

Android 线程交互

有关子线程对UI的线程更新的说法

iOS子线程操作UI

在主线程的密集功能期间 UI 未更新(在 Swift 中)