UIKit – Images and Graphics Best Praticies – 如安在app中高效运用图形内容的技能及策略

解决问题 – 怎么将先进的cpu和gpu技能集成到你的app中

当app中运用更多的cpu时,将会对电池寿命和app的呼应能力发生负面的影响

或许不那么明显的是,当你的app和系统上的其他app,耗费更多内存,也会导致更高的cpu运用率,这对电池寿命和性能有进一步的晦气影响

因而,咱们将重点重视怎么改善对这些资源的运用

关于这个问题的评论还有什么比一个需求处理很多图画内容的app为布景更适合的呢 比方Photos app

UIImages UIKits都是用于处理图形数据的高级类

咱们倾向于将app中的图形内容分为两类 – 富内容 [Content](如相片), 也能够作为UIKit中的数据类型 [Iconography 用来表明某些事物,例如显现在按钮中的图标]

ios图像和图形最佳实践(一)

ios图像和图形最佳实践(一)

UIImageView 是UIKit供给的用于显现 UIImage的类

若采用经典的MVC模型进行类比,UIImage能够被看作模型对象

UIImageView是一个视图,这些对象和视图肩负着在经典模型中的责任

UIImage担任加载图片内容, UIimageView担任显现和烘托它

ios图像和图形最佳实践(一)

ios图像和图形最佳实践(一)

Image Rending Pipline

ios图像和图形最佳实践(一)

烘托是一个连续性进程,而不是一次性事件

其实有一个躲藏的阶段, 对衡量app的性能至关重要,这个阶段被称为解码

为了评论解码,需求先评论一个叫做”缓冲区”的概念,

Custom region of memory – Often viewed as sequence of elements

ios图像和图形最佳实践(一)

缓冲区仅仅一段连续的内存区域,但咱们倾向于运用术语 “缓存”,来表明一系列元素组成的内存,这些元素具有相同的尺度,并一般具有相同的内部结构,而咱们重视的重点是其间一种非常重要的缓存 (即图画缓存)

ios图像和图形最佳实践(一)

咱们用这个术语来表明一种特定缓存,它保存了某些图画在内存中的表明,此缓存的每个元素描绘了图画中每个像素的色彩和透明度

因而这个缓存在内存中的巨细与它包含的图画巨细成正比

缓存的一个特别重要的比如是帧缓存

The frame buffer

ios图像和图形最佳实践(一)

帧缓存担任在你的app中保存实践烘托后的输出,因而当你的app更新其视图层次结构时,UIKit将重新烘托app的窗口及其所有子视图 到帧缓存中

ios图像和图形最佳实践(一)

该帧缓存供给每个像素的色彩信息,显现硬件将读取这些信息,以便点亮显现器上对应的像素

ios图像和图形最佳实践(一)

终究一部分以固定的时间距离发生

ios图像和图形最佳实践(一)

它或许以每秒60帧的频率发生,即每1/60秒发生一次

或在配备ProMotion Display的iPad上,它的速度能够到达1/120秒发生一次

ios图像和图形最佳实践(一)

假如你的app中没有任何改变,则显现硬件会将它上次看到的相同的数据从帧缓存中取出

ios图像和图形最佳实践(一)

可是当你改变视图的内容,比方你为图画视图指定了一个新的UIImage,UIKit将重新烘托你的app窗口

ios图像和图形最佳实践(一)

并将其放入帧缓存

ios图像和图形最佳实践(一)

ios图像和图形最佳实践(一)

下一次显现硬件从帧缓存中取出时,它将会得到你的新内容

ios图像和图形最佳实践(一)

ios图像和图形最佳实践(一)

现在你能够将图画缓存与另一种“数据缓存”进行比照

ios图像和图形最佳实践(一)

这仅仅一种包含一系列字节的缓存,在咱们的比如中,咱们关怀的是包含图画文件的数据缓存,也许咱们现已从网络上下载了,或许从磁盘中加载了它们(数据缓存)

包含图画文件的数据缓存一般以某些元数据最初,这些元数据描绘了存储在数据缓存中的图画巨细

然后包含图画数据本身,图画数据以某种形式编码 如JPEG紧缩或PNG

这意味着该元数据后面的字节实践上并不直接描绘图画中像素的任何内容,

因而,咱们能够深入了解下咱们设置的这条管道

这里有一个ImageView,而且咱们现已杰出显现了帧缓存的区域,这块区域将由图画视图进行烘托填充

ios图像和图形最佳实践(一)

咱们现已为这个图画视图分配了一个UIImage,它有一个表明图画文件内容的数据缓存,其或许是从网络下载或从磁盘读取的,但咱们需求用每个像素的数据来填充帧缓存

为了做到这一点,UIImage将分配一个图画缓存

Pipline in Action

ios图像和图形最佳实践(一)

其巨细等于包含在数据缓存中的图画的巨细,同时履行称为解码的操作,这将JPEG或PNG或其他编码的图画数据转换为每个像素的图画信息

ios图像和图形最佳实践(一)

然后取决于咱们的图画视图的内容模式

当UIKit要求图画视图进行烘托时,

ios图像和图形最佳实践(一)

它会在将数据复制到帧缓存的进程中,对来自图画缓存的数据进行复制和缩放

现在 解码阶段是CPU密集型的,特别是关于大型图画

因而 不是每次UIKit要求图画视图烘托时都履行一次这个进程

UIImage绑定在图画缓存上,所以它只履行一次这个进程

ios图像和图形最佳实践(一)

因而 你的app关于每个被解码的图画都或许会继续存在很多的内存分配

正如前面提到的那样,这种内存分配与输入图画的巨细成正比,而与帧缓存实践烘托的视图的巨细没有必然联系,而这会对性能发生一些适当晦气的结果

ios图像和图形最佳实践(一)

app地址空间的中的大块内存分配,或许会迫使其他相关内容远离它想要引证的内容 这种情况被称为碎片(乱用内存的结果)

假如你的app开端占用越来越多的内存 操作系统就会介入 并开端透明地紧缩物理内存的内容

除了你自己的app对CPU的运用之外,CPU也需求参与这个操作,你或许会添加你无法控制的大局CPU运用率

终究你的app或许会耗费过多的物理内存 以至于操作系统需求启动停止进程 它将从低优先级的后台进程开端

假如你的app耗费了到达特定数量的内存,你的app本身或许会被停止 而其间被停止的后台进程 或许正代表用户履行某些重要工作 因而他们或许一停止就当即重新启动
所以 即使你的app或许只会在短时间内耗费内存,它也或许对CPU运用率发生深远的影响 因而咱们希望削减app的内存运用量

咱们能够用一种称为 下采样 的技能来完成这一目标

现在 咱们来看一下 图画烘托管道的更多细节 包含咱们要在其间显现图画的图画视图,实践上比要显现的图画小这一事实

ios图像和图形最佳实践(一)

一般Core Animation框架在烘托阶段将担任缩小该图画 但咱们能够通过运用这种下采样技能来节约一些内存 本质上 咱们要做的便是捕捉该缩小的操作 并将其放入缩略图的对象中

ios图像和图形最佳实践(一)

咱们终究会削减内存运用量 因为咱们将有一个较小的解码图画缓存 这样咱们设置了一个图画源,创建了一个缩略图 然后将解码图画缓存捕获到UIImage中 同时将该UIImage分配给咱们的图画视图

咱们就能够丢掉包含咱们原有图片的数据缓存

ios图像和图形最佳实践(一)

其结果是咱们的app将具有一个更小的长时间内存占用脚印

履行该操作的代码有几个过程 咱们先简单过一遍这个流程 初步看下作用

咱们加载一张1.2M 3840×2400 的图片

ios图像和图形最佳实践(一)

不运用策略加载一张图片 耗费112M内存

ios图像和图形最佳实践(一)

运用downsample函数 耗费66.7M内存, 将近节约一半内存

ios图像和图形最佳实践(一)

ios图像和图形最佳实践(一)

起作用了 ……

ios图画和图形最佳实践(二)