线程安全的UIImage

我知道苹果正式推荐UIKit只能在主线程中使用。 不过,我也听说UIImage自iOS 4.0以来就是线程安全的。 我找不到任何支持这一说法的文件。

有没有人有任何信息来支持这一说法? 作为一个用于存储数据和解码图像数据的类,如果devise得当,UIImage应该是线程安全的。

确实,苹果推荐在主线程中使用来自UIKIt的元素:

注意:大多数情况下,UIKit类只能在应用程序的主线程中使用。 对于从UIResponder派生的类或者以任何方式涉及操纵应用程序用户界面的类尤其如此。

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

但是,这是基于我的经验,我还没有看到任何官方文件。

直接从苹果的UIImage的文件

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

(强调我的)

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

在iOS中的新增function:iOS 4.0发行说明中,UIKit Framework增强function包含以下内容:

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

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

看起来苹果公司已经更新了他们的文档,因为之前的答案已经发布了。 根据最新的文档,从任何线程创build和使用UIImage实例是安全的:

由于图像对象是不可变的,因此创build后不能更改其属性。 大多数图像属性是使用随附图像文件或图像数据中的元数据自动设置的。 图像对象的不可变性也意味着它们可以安全地从任何线程创build和使用

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

只是为了简短:UIImage不是线程安全的,或者更好的只能在主线程上工作,就像我在debugging后经历的那样。

我希望有帮助。 我希望从苹果公司得到更多的清楚,甚至更好的UIImage类,可以在不同的线程呈现。 不应该太难…

编辑:经过一番研究,我发现它是“UIGraphicsGetImageFromCurrentImageContext();” 导致麻烦。 这有点偏离主题,但也许这有助于: https : //coderwall.com/p/9j5dca

感谢Zachary Waldowski。

线程安全不是问题,因为任何线程都可以尝试同时访问上下文(并发)。 而且,虽然这通常是可以的,但在低内存的情况下,比如在iOS设备上使用Photo Editing Extension,访问一个上下文的两个线程会由于内存不足而崩溃。

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

因此,如果不了解线程和并发性,就不会认为自己的线程安全知识是完整的,对于关于线程安全性的问题,任何答案都是双重的。 总之:正确的问题是,线程安全性如何适用于内存使用情况,无论何时谈论image processing。

如果你只是在这里踢轮胎,你需要等待提出你的问题,直到你遇到了一个真正的问题。 但是,如果您计划下一步行动,则需要知道如何按顺序执行image processing命令,并且需要手动解除分配。 您必须devise您的应用程序,以便在内存中只有一个正在处理的图像副本。 永远不要依靠自动释放线程安全或不安全的方式来为你打电话。 不起作用。