我知道苹果公司官方推荐仅在主线程中使用UIKit。然而,我也听说自iOS 4.0起,UIImage是线程安全的。但我找不到任何支持这一说法的文档。
有没有人有相关信息来支持这一说法?作为用于存储数据和解码图像数据的类,如果设计得当,UIImage应该是线程安全的。
我知道苹果公司官方推荐仅在主线程中使用UIKit。然而,我也听说自iOS 4.0起,UIImage是线程安全的。但我找不到任何支持这一说法的文档。
有没有人有相关信息来支持这一说法?作为用于存储数据和解码图像数据的类,如果设计得当,UIImage应该是线程安全的。
直接引用来自苹果的UIImage文档
图像对象是不可变的,因此在创建后无法更改其属性。这意味着通常在初始化时指定图像的属性或依靠图像的元数据提供属性值。这也意味着图像对象本身可以从任何线程安全使用。 要更改现有图像对象的属性,请使用其中一个可用的方便方法来创建图像的副本,但带有您想要的自定义值。
(强调是我加的)
因此,至少在2014年5月13日的SDK的当前版本中,“图像对象本身可以从任何线程安全使用”。
imageWithData:
从不同的线程初始化许多UIImages时发现的那样。请参见此处:https://github.com/AFNetworking/AFNetworking/pull/2860 - Eric GUIImage
初始化程序,现在我又得到了一个线索。谢谢。 - eonil苹果公司确实建议在主线程上使用UIKIt中的元素:
注意:在大多数情况下,UIKit类应该只从应用程序的主线程使用。特别是那些派生自UIResponder或涉及以任何方式操作应用程序用户界面的类。
由于UIImage没有派生自UIResponder,并且您实际上没有在界面/屏幕上显示它。因此,在另一个线程上使用UIImages进行操作应该是安全的。
但是,这是基于我的经验,我没有看到任何官方文档支持这一点。
简单来说: UIImage不是线程安全的,或者更好地说,只能在主线程上工作, 我在当前的调试中经历过这种情况。
我希望这可以帮助您。 我希望从苹果公司获得更多关于此事的明确性, 甚至最好是一个UIImage类,可以在不同的线程中呈现。 这应该不太困难...
编辑: 经过一些研究,我发现是“UIGraphicsGetImageFromCurrentImageContext();” 引起了麻烦。 这有点偏题,但也许这有所帮助: https://coderwall.com/p/9j5dca
感谢Zachary Waldowski。
线程安全不是问题,因为任何线程都可以同时(并发)尝试访问上下文。虽然这通常没问题,但在低内存情况下,例如在iOS设备上的照片编辑扩展中,两个线程访问一个上下文可能会由于内存不足而导致应用程序崩溃。
当混合使用Core Image滤镜和vImage操作时会出现这种情况。两者都是线程安全的,但ARC在处理Core Image对象之前不会释放vImage缓冲区数据,因此在内存中会有两份图像副本。
因此,在谈论图像处理时,您永远不应认为自己对线程安全的了解已经完整,除非您理解了线程和并发性——这对于任何关于线程安全的问题都是如此重要。简而言之:正确的问题是,无论何时谈论内存使用情况,线程安全如何应用于图像处理。
如果您只是在试水,请等到遇到真正的问题再提出您的问题。但是,如果您正在计划下一步行动,您需要知道如何按顺序执行图像处理命令,并进行手动释放。您必须设计您的应用程序,以便在内存中只有一个图像副本被处理。永远不要依赖自动释放——无论是否线程安全——来为您做出决定。这是行不通的。