【发布时间】:2019-01-04 03:49:38
【问题描述】:
我写了一个名为ensureInMainThread 的小定义(我经常使用它)。但是,我不确定在主线程上调用了哪些用户界面方法需要。 setNeedsDisplay 和 setNeedsLayout 呢? iOS 5.x 中需要在主线程上调用的方法的经验法则是什么?
这些问题是相关的(一些低质量的问题和答案,以及一些非常具体的案例),但我想要一个全面、单一的好答案:
【问题讨论】:
我写了一个名为ensureInMainThread 的小定义(我经常使用它)。但是,我不确定在主线程上调用了哪些用户界面方法需要。 setNeedsDisplay 和 setNeedsLayout 呢? iOS 5.x 中需要在主线程上调用的方法的经验法则是什么?
这些问题是相关的(一些低质量的问题和答案,以及一些非常具体的案例),但我想要一个全面、单一的好答案:
【问题讨论】:
从 iOS 4.0 开始,some user interface updates can be performed on a background thread:
在 UIKit 中绘制到图形上下文现在是线程安全的。具体来说:
用于访问和操作图形上下文的例程现在可以正确处理驻留在不同线程上的上下文。
字符串和图像绘制现在是线程安全的。
现在可以安全地在多个线程中使用颜色和字体对象。
David Duncan 在他的 cmets here 中证实了这一点。
除此之外,几乎所有与 UIKit 相关的东西都不是线程安全的,因此在这些情况下,您应该确保在主线程上与它进行交互。
顺便说一句,我更喜欢my block-based implementation of a "always run on the main thread" function 而不是您链接到的宏,因为我喜欢需要在主线程上运行的代码的显式包装。
【讨论】:
setNeedsDisplay 和setNeedsLayout,以及是否可以从另一个线程安全地调整UILabel 上的字符串?
-setNeedsDisplay 是安全的,因为围绕绘制上下文的保护措施,但我不确定-setNeedsLayout。我相信后者可能不安全,因为这不是处理绘图,而是视图和图层的定位。我觉得UILabel的文字绘制应该是安全的,但是我自己没有测试过。
经验法则:任何更新界面的东西都必须在主线程上。
【讨论】:
在 iOS 12 中,如果您从后台线程调用 setNeedsDisplay,您会得到以下断言:
主线程检查器:在后台线程上调用的 UI API:-[UIView setNeedsDisplay]
【讨论】: