需要在主线程上运行的内容是什么?

6
我写了一个小定义叫做ensureInMainThread(我经常使用它)。然而,我不确定哪些用户界面方法需要在主线程上调用。例如setNeedsDisplaysetNeedsLayout?在iOS 5.x中,需要在主线程上调用的方法有什么规则?这些问题是相关的(一些低质量的问题和答案,以及一些非常具体的情况),但我想要一个全面的、单一的好答案:
3个回答

9
自iOS 4.0起,可以在后台线程上执行一些用户界面更新
  • 在UIKit中绘制图形上下文现在是线程安全的。具体来说:

    • 用于访问和操作图形上下文的例程现在可以正确处理驻留在不同线程上的上下文。

    • 字符串和图像绘制现在是线程安全的。

    • 在多个线程中使用颜色和字体对象现在是安全的。

David Duncan在他的评论 这里 中证实了这一点。

除此之外,关于UIKit的几乎所有其他内容都不被认为是线程安全的,因此在这些情况下,您应该确保在主线程上与其交互。

作为一个旁白,我更喜欢我的基于块的“始终在主线程上运行”的实现,而不是你链接的宏,因为我喜欢明确包装需要在主线程上运行的代码。

Bravo,一如既往地+1,感谢Brad Larson。这就是我一直在寻找的答案(尽管我无法想象它)。您能否评论一下setNeedsDisplaysetNeedsLayout,以及是否可以安全地从另一个线程调整UILabel上的字符串? - Dan Rosenstark
1
@Yar - 我认为-setNeedsDisplay是安全的,因为它涉及到在上下文中进行绘制的保护措施,但我不确定-setNeedsLayout是否安全。我认为后者可能不安全,因为它不涉及绘图,而是涉及视图和图层的定位。我认为UILabel的文本绘制应该是安全的,但我自己还没有测试过。 - Brad Larson

3

经验法则:更新界面的任何操作都必须在主线程上执行。


3
正如我在回答中指出的那样,从 iOS 4.0 开始,UIKit 中现在有一些是线程安全的。 - Brad Larson

0
在iOS 12中,如果你从后台线程调用setNeedsDisplay方法,你会得到以下断言:

主线程检查器:在后台线程上调用了UI API:-[UIView setNeedsDisplay]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接