WatchOS:是否应该在主线程上调用来自扩展的 UI 更新



对于 iOS 应用程序,UI 更新仅从主线程完成 - 从不建议不这样做,这可能会导致意外行为。

在 watchOS 中,操作系统由监视扩展和应用程序构成 - 作为不同的"容器"。通常,UI 更新是从扩展调用的,这些更新会更新应用容器中的某些内容。

相同的主线程逻辑是否适用于从监视扩展更新 UI,或者是否可以从后台调用 UI 更新?


编辑 - 带来一些清晰度。从应用程序的容器中,UI 更新可能应该在主线程上进行(就像在大多数系统/操作系统中发生的那样,如下所述(。问题实际上是watchOS是否为我们处理了这个问题,即在扩展的后台线程上调用UI更新是否会自动发布到应用程序容器的主线程中。

Apple 的

watchOS 应用程序编程指南可能是权威指南,但我找不到关于在主线程以外的线程上进行 UI 更新的参考。

有人会认为,如果从主线程调用 UI 更新很重要,它会在某处明确声明(就像它在 iOS 应用程序编程指南中的线程和并发部分所做的那样(:

涉及视图、核心动画和许多其他 UIKit 类的工作 通常必须发生在应用的主线程上。有一些例外 对于此规则,例如,基于图像的操作通常可能发生在 后台线程 — 但如有疑问,请假设需要进行工作 在主线程上。

不过,上面的引用也可以解释为适用于手表扩展的 UI 更新,因为它在 iOS 上运行。

综上所述,我不相信有任何Apple文档以一种或另一种方式说明。

不过,这是另一个数据点:Apple的Lister示例代码现在包含一个WatchKit扩展,根据我对它的简要研究,它似乎将获取调度到后台队列(参见ListInfo.swift:34(,并通过调度回主队列来更新UI(ListsInterfaceController.swift:98(。那里甚至有一条评论说它正在这样做:

The fetchInfoWithCompletionHandler(_:(方法在后台调用其完成处理程序 队列,调度回主队列以进行 UI 更新。

我认为基于上述内容,我会在主线程上进行更新方面犯错误,除非您确定这样做有性能或其他影响。

通过技术支持事件联系 Apple 后,收到的答案和解释如下。

TLDR:使用主线程。

所有更新都应从主线程完成。 这一直 是UIKit的一般建议,并且该建议 扩展到 watchOS。

了解其根本原因可能会有所帮助 要求。 请记住,即使使用集中式通信 通道来序列化更改,当您尝试 从后台线程操作 UI 状态。 例如,虽然 序列化通道可以防止多个 UI 命令尝试 要同时执行,它无法控制 将执行不相关的命令。 考虑以下 2 个块:

block 1 {     
  DoUIChange1     
  DoUIChange2     
}
block 2 {     
  DoUIChange3     
  DoUIChange4     
}

如果两个块都在主线程上执行,则实际 命令流为:

DoUIChange1   
DoUIChange2   
DoUIChange3   
DoUIChange4

或。。。

DoUIChange3   
DoUIChange4   
DoUIChange1   
DoUIChange2

但是,如果两个块都在自己的线程上执行,则更多 可能性打开:

DoUIChange3   
DoUIChange1   
DoUIChange2   
DoUIChange4

或。。

DoUIChange1   
DoUIChange3   
DoUIChange2   
DoUIChange4

或。。

DoUIChange1   
DoUIChange3   
DoUIChange4   
DoUIChange2

等。。。

不用说,如果UI代码很复杂,那么数量 组合很快就会变得巨大,造成意想不到的 UI 错误 基本上是不可避免的。

应始终在主线程上进行 UI 更新。否则将导致 UI 呈现速度变慢或潜在的应用崩溃。这不是特定于iOS或watchOS,因为几乎所有编程语言(C#,Java,C++等(都要求您在主线程上进行UI更新。

在watchOS 1中,您的建议可能是有意义的,因为扩展程序在iPhone上,而UI在手表上。在这种情况下,应用确实作为两个单独的进程运行,并且您"可能"不需要调度到主线程进行 UI 更新。但在watchOS 2中,情况有所不同。即使认为watchOS扩展和UI有不同的目标,在watchOS 2中,它们不会在手表上作为单独的进程运行(您可以通过在Xcode中查看Apple Watch上的正在运行的进程来验证这一点,并看到每个应用程序只有一个(。仅仅因为它被打包为两个单独的容器(甚至签名不同(并不意味着它们在手表上作为两个单独的进程运行。

最新更新