UIImage的线程安全性

时间:2012-05-18 00:38:32

标签: objective-c ios thread-safety

我知道Apple正式建议仅在主线程中使用UIKit。但是,我也听说过自iOS 4.0以来UIImage是线程安全的。我找不到支持此声明的任何文档。

是否有人有任何信息支持此声明?作为用于存储数据和解码图像数据的类,如果设计得很好,UIImage应该是线程安全的。

6 个答案:

答案 0 :(得分:26)

直接来自Apple's documentation for UIImage

  

图像对象是不可变的,因此您无法在创建后更改其属性。这意味着您通常在初始化时指定图像的属性,或者依赖图像的元数据来提供属性值。 这也意味着图像对象本身可以安全地从任何线程使用。更改现有图像对象属性的方法是使用一种可用的便捷方法来创建图像的副本但是使用您想要的自定义值。

(强调我的)

至少在截至2014年5月13日的SDK的当前版本中,“图像对象本身可以安全地从任何线程使用。”

答案 1 :(得分:5)

Apple确实建议在主线程上使用UIKIt中的元素:

  

注意:在大多数情况下,UIKit类只能用于   应用程序的主要线程。对于课程尤其如此   源自UIResponder或涉及操纵你的   应用程序的用户界面。

由于UIImage不是从UIResponder派生的,因此您实际上并未在界面/屏幕上显示它。然后在另一个线程上使用UIImages进行操作应该是安全的。

然而,根据我的经验,我还没有看到任何关于它的官方文件。

答案 2 :(得分:2)

What's New in iOS: iOS 4.0发行说明中,UIKit Framework增强功能包含以下内容:

  

在UIKit中绘制图形上下文现在是线程安全的。   具体来说:用于访问和操作图形的例程   上下文现在可以正确处理驻留在不同的上下文   线程。字符串和图像绘制现在是线程安全的。使用颜色和   现在可以安全地使用多个线程中的字体对象。

所以UIImage在iOS 4.0及更高版本中是线程安全的。

答案 3 :(得分:2)

看起来Apple已更新了他们的文档,因为此处的早期答案已发布。根据最新的文档,从任何线程创建和使用UIImage实例是安全的:

  

因为图像对象是不可变的,所以你无法改变它们   创建后的属性。大多数图像属性是自动设置的   在附带的图像文件或图像数据中使用元数据。该   图像对象的不可变性也意味着它们安全   从任何线程创建和使用

https://developer.apple.com/reference/uikit/uiimage

答案 4 :(得分:1)

简而言之: UIImage不是线程安全的,或者更好只适用于主线程, 正如我在调试后经历的那样。

我希望有所帮助。 我希望Apple能够更清楚地了解这一点 甚至更好的UIImage类,可以在不同的线程中呈现。 不应该太难......

编辑: 经过一番研究,我发现它是" UIGraphicsGetImageFromCurrentImageContext();" 这会引起麻烦。 它有点偏离主题,但也许这会有所帮助: https://coderwall.com/p/9j5dca

感谢Zachary Waldowski。

答案 5 :(得分:0)

线程安全不是问题,因为任何线程都可以尝试同时访问上下文(并发)。而且,虽然这通常没问题,但在内存不足的情况下,例如iOS设备上的照片编辑扩展,访问一个上下文的两个线程可能会因内存不足而导致应用程序崩溃。

将Core Image过滤器与vImage操作混合时会发生这种情况。两者都是线程安全的,但ARC在处理Core Image对象之前不会释放vImage缓冲区数据,所以你在某些时候在内存中有两个图像副本。

因此,在不了解线程和并发性的情况下,您永远不会认为您对线程安全的了解是完整的 - 对于线程安全问题的任何答案都是双倍的。简而言之:正确的问题是,无论何时你谈论图像处理,线程安全如何适用于内存使用。

如果您只是在这里踢轮胎,您需要等待提出问题,直到您遇到真正的问题。但是,如果您正在计划下一步行动,则需要知道如何按顺序执行图像处理命令,以及手动释放。您必须设计应用程序,以便在内存中只处理一个正在处理的图像副本。永远不要依赖自动释放 - 线程安全或不 - 为您打电话。它不会工作。