示例:[UIImage imageWithData:pngData]
它是在内部存储实际编码的字节并按需解压缩,还是永久解压缩为原始像素或其他格式?
解决方法
测试分两步完成
>只需加载图像并将其存储在一个数组中.
>单独的按钮为每个图像创建UIImageViews并显示它们.
结果如下:
[UIImage imageNamed:]
步骤1:内存仅增加大约所有jpeg2000文件的总和(每个大约50K,因此内存增加了大约5 MB).我假设此时重复文件没有重复,并且以某种方式由iOS进行整合,因为如果没有重复检查,此时内存将增加10MB.
第2步:内存显着增加(大约200 MB),大概是因为图像被解码为BGRA格式,准备在UIImageView中显示.看起来在这个阶段没有重复的过滤,并且为每个图像分配了单独的原始内存.我不确定为什么,但这比实际的原始像素内存使用量大约多80 MB.
[UIImage imageWithContentsOfFile:]
步骤1:内存使用与[UIImage imageNamed:]相同,因此在此阶段有重复过滤.
第2步:内存使用量增加到130 MB.由于某种原因,这比[UIImage imageNamed:]低70 MB.此数字更接近200张图像的预期原始像素存储量.
[UIImage imageWithData:]
首先使用[NSData dataWithContentsOfFile:].
第1步:内存使用量为15 MB.我假设这里没有重复过滤,因为它接近所有jpeg2000数据的总文件大小.
第2步:内存使用量增加到139 MB.这不仅仅是[UIImage imageWithContentsOfFile:],而是远远不够.
iOS似乎引用了使用上述三种方法加载的UIImage的压缩数据,直到实际需要原始像素为止,此时它被解码.
[UIImage imageNamed:]因为我的所有图像视图都引用了图像,因此永远不会释放内存.如果我交错加载并允许运行循环执行,它将释放未引用的图像的内存.一个优点是对同一图像的重复[UIImage imageNamed:]调用基本上是免费的.不要将此方法用于GUI图像以外的任何其他方法,否则可能会耗尽内存.
[UIImage imageWithContentsOfFile:]在内存使用方面的行为类似于[UIImage imageNamed:],直到需要原始像素为止,此时由于某种原因,它在内存使用方面效率更高.当解除分配UIImage时,此方法还会立即释放内存.使用相同文件重复调用[UIImage imageWithContentsOfFile:]似乎使用缓存副本,直到所有引用该文件的UIImage都被释放.
[UIImage imageWithData:]不进行缓存或重复检查,并始终创建新图像.
我测试了与PNG文件相同的集合,imageNamed和imageWithContentsOfFile的步骤1结果显示使用的内存更少(约0.5 MB),imageWithData显示压缩的所有PNG文件的总和.我的猜测是iOS只是存储对文件的引用,并且在解码时间之前不会对其执行任何其他操作. PNG的步骤2结果是相同的.