目前dome已经做好啦,但是感觉自己理解还不是很透彻。打算改下自己的博客从头开始对博客进行重新更新,更新时间7/16/2016。
下面给出界面优化知识思维导图

今天也打算写关于图片、音频和视频在深层原理,以及图像在屏幕显示原理以及后面提出如何进行在此方面优化。
下面就讲述在IOS开发过程中经常使用的UIView和CALayer两者之间的关系和在动画使用过程的具体封装(网上也有许多关于这个话题的文章,也是站在巨人肩膀上)。
UIView 和 CALayer之间的关系
打开 UIView 和 CALyer 中实际实现的代码,下面是UIView实现源码:
UIView头文件:
1 | NS_CLASS_AVAILABLE_IOS(2_0) @interface UIView : UIResponder <NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusEnvironment> |
CALayer源文件:
1 | //CALayer实现源码: |
我们可以看出 UIView 是继承自 UIResponder,而 CALayer 继承自NSObject。这也是 UIView 可以相应触摸事件,并实现响应链中最后一环所在后面我们会具体讲述。CALayer 继承自 NSObject,其中 UIView 中又包含自己所特有的 layer。我们可以看做 CALayer 是 UIView 的具体内容细节的实现,两者具有平行关系。
为什么不把两者何在一起进行实现呢,分开实现具体功能呢?
我想可能是为啦分层需要,把功能具体分隔开来。UIView实现触摸响应,CALayer实现具体的内容展示。
下面我们将写关于 UIView 和 CALayer 的一些相关的知识:
列出在 UIView 实现不了的 CALayer 的功能:
- 阴影,圆角,带颜色的边框
- 3D变换
- 非矩形范围
- 透明遮罩
- 多级非线性动画
我们也都知道在 iPhone 手机内存是固定不能进行拓展,所以我们手机内存是很宝贵的。如果我们想要加载大容量的图片,会占用很大的内存。
为此,Apple 采用了一种比较巧妙的策略。在低内存的情况下,系统会强制清除 UIImage 对象所指向的图片数据,以释放部分内存。注意,这种清除行为影响到的只是图片数据,而不会影响到 UIImage 对象本身。当我们需要绘制那些图片数据已经被清除的UIImage 对象时,对象会自动从源文件中重新加载数据。当然,这是以时间换空间的一种策略,会导致一定的性能损耗。下面给出一些图片处理小技巧
UIImage缓存
我们知道在使用 imageNamed 进行图片显示,图片会缓存。但具体缓存是怎么实现,其中解析和清除时间是什么时候呢?
当我们使用
imageNamed:时创建图片,系统会通过Bundle的文件中找到图片的文件名,然后把相关的名字放到UIImage返回,此时并没有解析图片。当图片在第一次显示时,图片才会调用内部解码方法,解码会放到一个全局变量中。图片在解码后,会在App第一次进入后台或者内存警告时,该图片的缓存才会被清空,其他情况缓存会一直存在。
使用 imageWithData 可以避免缓存吗?
我们在创建 UIImage 时,UIImage的底层会调用 ImageIO的CGImageSourceCreateWithData(),此方法有个参数 ShouldCache,在 64 位的处理器上是默认开启的。图片也会在第一次显示在屏幕上才会被解码,解码数据也会保存在CGimage 的内部。
但是与上面使用 imageName 的情况不同,在 UIImage 被释放是其缓存也会进行释放。
怎样避免缓存
- 上面我们可以看到如果直接使用
CGImageSourceCreateWithData(),并且关闭ShouldCache和ShouldCacheImmediately,但是这样的话每次图片需要显示的话,都会进行图片解码,这样会占用较大CPU - 把图片用
CGContextDrawImage()绘制到画布上,然后把画布的数据取出来当作图片。这也是常见的网络图片库的做法。
后面小编将分出一篇文章专门讲述空间绘制的博文。
参考资料:
处理图片的一些小 Tip
内存恶鬼drawRect
图层的树状结构
寄宿图
UIView和CALayer总的参考地址
UIVie和CALayer关系源码;