IOS CoreAnimate 东西比较多,这篇笔记是入门用的,主要讲述的是静态的图形绘画处理问题。(当然动画也只是一小部分)理解相关的概念问题:
- 参考资料
http://segmentfault.com/a/1190000000390012 (非常好的文章,受益匪浅,关键词:离屏渲染)
工具:Instrument的Core Animation 有一个叫做Color Offscreen-Rendered Yellow的选项。它会将已经被渲染到屏幕外缓冲区的区域标注为黄色(这个选项在模拟器中也可以用)。同时确保勾选Color Hits Green and Misses Red选项。绿色代表无论何时一个屏幕外缓冲区被复用,而红色代表当缓冲区被重新创建。
阐述提炼:一般来说,你需要避免离屏渲染。因为这个开销很大。在屏幕上面直接合成层要比先创建一个离屏缓存然后在缓存上面绘制,最后再绘制缓存到屏幕上面快很多。这里面有2个上下文环境的切换(切换到屏幕外缓存环境,和屏幕环境)。
产生离屏渲染的情况:如果你直接或是间接的给一个层增加了遮罩。Core Animation 会为了实现遮罩强制做离屏渲染。这个增加了GPU的负担,因为一般上来,这些都是直接在屏幕上面渲染的。
如果你使用的层引发了离屏渲染,那么你最好避免这种方式。还有设置圆角,设置阴影都会造成离屏渲染。
应用:对于遮罩来说,圆角只是一个特殊的遮罩。clipsToBounds 和 masksToBounds 2个属性而已。你可以简单的创建一个已经设置好遮罩的层创建内容。比如,使用已经设置了遮罩的图片。当然,这个也是一种权衡。如果你希望在层的contents属性这只一个矩形的遮罩,那你更应该使用contentsRect而不是使用遮罩。
http://www.hrchen.com/2013/05/performance-with-instruments/ (简洁,快速浏览)
设置透明度的影响,wwdc相关的教程:
- WWDC 2012:
-
- 406: Adopting Automatic Reference Counting
- 238: iOS App Performance: Graphics and Animations
- 242: iOS App Performance: Memory
- 235: iOS App Performance: Responsiveness
- 409: Learning Instruments
- 706: Networking Best Practices
- 514: OpenGL ES Tools and Techniques
- 506: Optimizing 2D Graphics and Animation Performance
- 601: Optimizing Web Content in UIWebViews and Websites on iOS
- 225: Up and Running: Making a Great Impression with Every Launch
- WWDC 2011:
-
- 105: Polishing Your App: Tips and tricks to improve the responsiveness and performance
- 121: Understanding UIKit Rendering
- 131 performance optimization on iphone os
- 308: Blocks and Grand Central Dispatch in Practice
- 323: Introducing Automatic Reference Counting
- 312: iOS Performance and Power Optimization with Instruments
https://github.com/AttackOnDobby/iOS-Core-Animation-Advanced-Techniques (这本书好)
- 应用优化APP
实际例子应用:常见的应用开发中,使用圆角的icon,最简单的方式,设置View的Layer,设置圆角的弧度宽度等。
a.最直接的做法:我们直接在cellForRowAtIndexPath代理中,设置:
甚至设置阴影等效果。更具上面的介绍,已经清楚的知道:
这个view会经过离屏渲染,然后再输出到屏幕上,每次都会重绘边框,再整个cell输出到我们见到的视图上。可以通过自带的视图展示工具查看视图结构:
接着通过一些检测工具,我这边使用的是:KMCGeigerCounter,自带的检测工具也有,都可以。
可以用Instrument的Core Animation分析可以看到,图片使用的是离屏渲染技术,还是一整个矩形。(可以对比其他知名软件,qq,微信等)
可以看到非常的卡,体验非常差。占用内存情况增大,这里我特意使用了一张大的图片,方便查看比较。(11.3MB 37帧数快速滑动的时候)
接着,进行改良优化,把上面的圆角这些设置放到cell初始化中。(11.3MB 40帧数快速滑动的时候)数据上看,改良了一点点,还是不可容忍的卡。
这样子是不行的,分析一下,原因,每一个cell中,就算是重用,view中的内容改变了,其实Layer还是重新进行渲染的,渲染的时候,还有转折输出两次。
我们考虑用一个方法,自己手绘一个layer,他如果本来就不是方形的,本来就是圆角的话呢?试一下:
我这里使用的是方法二,简洁,容易修改。逻辑原理都是一样的。
运行测试,效果挺好的,mark一下,总算不卡了。
这里申明一下,查阅资料的时候:layer 的 masksToBound 和 clipsToBounds 上效果是一样的,同一个接口来的,view是封装了layer改了个名字而已。我测试了,帧数没有变化,看着别人clang出来的源码也是没有变化的,不服来辩,请上源码。