Core Animation 文档翻译 (第八篇)—提升动画的性能

前言


核心动画是提升基于APP动画帧率的好方式,可是核心动画的使用不表明性能的提高的保证。尤为在OSX,当使用核心动画时,咱们仍需选择最有效的方式。和全部的性能相关的问题同样,咱们应该使用工具时时的评估和跟踪APP的性能,以致于咱们可以确保性能是提高而不是退化的。
缓存

 

综合的建议和技巧



有如下几种方式能让咱们的Layers更有效的实现效果。对于任何优化来讲,咱们应该在尝试优化前先测量当前代码的性能;根据未优化以前的性能检测结果,可以让咱们知道所作的优化是否提高了性能。
安全

 

尽量的使用不透明的Layers


设置opaque为YES,可让核心动画知道它不须要为Layer保存透明通道。没有透明通道意味着合成器不须要使用Layer的background content渲染Layer,这就会为渲染节省时间。注意,这个属性的重要意义主要体如今:app

  • 做为layer-backed view(iOS内全部的View自带的Layer都是此种类型的)Layer。
  • CoreAnimation为Layer建立的bitmap。
    若是咱们直接将image关联到Layer的contents属性时,图片透明通道的保存将会无视Layer的opaque属性。

此处我的以为,不得不提下opaque属性的定义,由于它指出了更多的优化说明。Opaque定义为——它的默认值为NO,若是咱们的APP在绘制了彻底不透明的content填充整个Layer的bounds,那么设置这个属性为YES,能够是系统优化Layer的渲染。尤为是,当Layer经过绘制方法建立backing store,核心动画忽略backing store的透明通道。这么作可以提高图形合成器的性能。若是咱们设置这个属性为YES,咱们就必须将整个Layer的bounds区域使用不透明的内容填充。
仅当backing store被核心动画管理时,设置为YES才有效。若是咱们为contents属性关联一张带有透明通道的图片,图片将会保持它的透明通道,而忽视这个属性的值。

异步

 

简单的路径使用CAShapeLayer对象


CAShapeLayer类在合成图像的时候将咱们提供的path渲染成bitmap图片,并使用这个bitmap图片做为content。CAShapeLayer的优势是它奥那个是尽肯能以最好的分辨率绘制path,同时这个优势也会耗费额外的渲染时间。若是咱们提供的path属于复杂型的,光栅化那个path会花费更高的代价;若是Layer的size频繁改变(它将会被频繁重绘),大量的时间花费在绘制上就会变成性能瓶颈。async

为shape layer缩小绘制时间的一种方式是,将复杂的形状拆分为多个简单的形状。使用简单的paths并将一个一个的CAShapeLayer作成层次化结构,相对于一次绘制一个复杂的path,这么作可以提高速度;这是由于绘制操做在CPU上,而合成任务发生在GPU上。正如这个本质的简化,潜在的性能提高取决于咱们的content是什么样的;所以在作优化以前先测量记录当前代码的性能是很重要的,咱们能够拿优化前的性能和优化后的做对比,便于知道优化是否起做用了。工具

 

明确地为多个彻底相一样貌的Layer设置contents


若是咱们为多个Layer对象使用相同的image,那么就本身加载image并直接将其关联到那些Layer对象的contents属性。将image关联到contents属性可以阻止Layer 为backing store申请(alloca)内存;相反,Layer使用这个被提供的image做为它的backing store。当几个Layer使用相同的image的时候,这意味着这几个Layer是共享内存的而不是每个都为image开辟新的内存。性能

我的看来,保持image的缓存确实从两个角度节省了内存—避免再次使用从新建立,为多个相同Layer保持一分内存优化

 

保证设置Layer的size为整数值


为了达到最好的效果,须要保证Layer对象的width和height为整数值。尽管咱们可使用float值设置Layer的bounds,但最终Layer的bounds是被用于建立bitmap image,为宽和高指定整数值可以简化核心动画的工做(核心动画建立和管理backing store以及其余Layer信息)。动画

 

若是有必要,就使用异步Layer渲染


在代理方法drawLayer:incontext:或者view的drawRect:方法中作的任何事情,正常状况下是在APP的主线程发生的。再某些状况下同步绘制content可能会展示较差的性能。若是咱们注意到咱们的动画性能差时,咱们能够尝试开启Layer的 drawsAsynchronously 属性,这么作会将绘制操做移到非主线程,这么作也须要确保咱们的绘制代码是线程安全的。像以往同样,咱们应该在开启异步以前,先进性性能测量记录,而后和开启异步后的性能做对比。线程

 

当为Layer添加阴影时,先指定一个阴影path


让核心动画绘制阴影的形状将会耗费重大,而且会影响APP的性能。用Layer的showPath属性明确地指出阴影形状,能够提高性能。当咱们为这个属性指定path对象,核心动画使用那个shape绘制并缓存阴影效果。对于那些shpae几乎永远不会改变的Layers,这将会经过减小核心动画大量的渲染,从而很大程度的提高性能。

我的以为此处须要提下shadowpath属性相关:默认值为nil,layer使用标准的shadow形状。若是咱们指定一个值,layer将会使用指定的path建立他的shadow,而不是Layer的合成的透明通道。咱们提供的path定义了shadwo的轮廓,它将被填充(使用非零缠绕规则和当前的shadow颜色、opacity和模糊成都)。
不想许多可动画属性,这个属性(和其余CGPathRef可动画属性同样)不支持隐式动画。不过,path队形能够经过任何CAPropertyAnimation具体的子类作动画。Path将会以线性插值在线上的点;不在线上的点将会以非线性插值(为了保证曲线倒数的连续性)。若是两个paths有不一样的控制点或者片断,结果将会是未知的。若是path延伸到Layer的bounds外面了,正常的Layer遮盖规则就会将超出的地方裁剪。 指定显式的路径一般会提高渲染性能。 使用Core Foundation的retain/release语法,这个属性值会被retained。尽管这个属性是使用assign语法来持有的,retain行为仍是会出现。

相关文章
相关标签/搜索