【问题标题】: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 更新应该在主队列上完成。

标签: ios grand-central-dispatch


【解决方案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
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    相关资源
    最近更新 更多