微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

iOS UIImage存储格式,内存使用和编码/解码

iOS如何存储从压缩数据(jpeg2000,png,jpg等)加载的图像

示例:[UIImage imageWithData:pngData]

它是在内部存储实际编码的字节并按需解压缩,还是永久解压缩为原始像素或其他格式?

解决方法

我在iPad 2上创建了一个测试应用程序,使用以下三种方法加载了200个384×384像素的jpeg2000图像文件(117,964,800字节的原始像素):[UIImage imageNamed],[UIImage imageWithContentsOfFile:]和[UIImage imageWithData]. jpeg2000文件集是100个纹理,然后我将其复制到一个带有“copy”后缀的额外100个文件中,以查看iOS是否进行了任何重复的文件检查.更多关于下面的内容.

测试分两步完成

>只需加载图像并将其存储在一个数组中.
>单独的按钮为每个图像创建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结果是相同的.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐