我们是不是需要在主线程或主队列中更新 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?的主要内容,如果未能解决你的问题,请参考以下文章