对基于 app 的动画,Core Animation 是提升帧速率很好的方式,但并非使用它必定能提升性能。尤为在 OS X ,你仍必须作出选择关于使用 Core Animation 行为最高效的方法。全部性能相关的问题,你应该使用 Instruments 随时间的推移去测量、追踪你 app 中的性能,这样你就能肯定性能确实提升了,而不是更慢了。html
NSView
类默认的重绘策略是保存类的原始绘制行为,即便视图是图层支持视图。若是你在 app 中使用图层支持视图,你应该检查重回策略,选择能为你 app 提供最好性能的方式。在多数状况下,默认的策略并非能提供最好性能的。而 NSViewLayerContentsRedrawOnSetNeedsDisplay 策略更可能减小你 app 的绘制数量、提高性能。其它策略可能对具体类型的视图会提供更好的性能。缓存
关于视图重绘策略的更多信息,请参见OS X 视图的图层重绘策略会影响性能。安全
在 OS X v10.8 及之后版本,视图有两个选项来更新底部图层的内容。你在OS X v10.7及之前版本更新图层支持视图时,图层将视图 drawRect:
方法中的绘图命令捕获到背景位图图像中。缓存绘制命令是高效的,当它不是在全部状况下都是最高效的。若是你知道如何直接提供图层的内容,而不用真正地渲染它们,你可使用 updateLayer
方法去实现。app
关于渲染的不一样路径的更多信息,包含涉及 updateLayer
方法,请参见使用委托提供图层内容。异步
这有几种方法使你的图层实现更加高效。然而,与以前的优化同样,在尝试优化以前,你始终应该测量代码的当前性能。 这为你提供了基准线,你可使用它来肯定优化是否有效。ide
将图层的 opaque
属性设置为 YES
,让 Core Animation 知道它不须要操做图层的 alpha 通道。没有 alpha 通道意味着合成器不须要将图层内容和背景内容混合,这会在渲染期间节省时间。然而,该属性主要与做为图层支持视图的一部分的图层,或 Core Animation 建立底层位图的状况相关。若是你直接给图层的 contents
属性赋值图像,图像的 alpha 通道都会被保留,无论 opaque
属性的值是什么。性能
CAShapeLayer 类经过将你提供的路径在合成时渲染成位图图像,来建立它的内容。这样作的优势就是图层老是以最好的分辨率绘制路径,可是这个优势也形成了额外的渲染时间。若是你提供的路径是复杂的,光栅化路径可能会很是耗时间。若是图层的尺寸常常变化(确定会常常重绘),花费在绘制上的时间会累积起来,成为性能瓶颈。优化
减小图形图层绘制时间的方法就是将复杂图形分割成简单图形。合成器使用简单路径去绘制多个 CAShapeLayer 对象并拼接在一块儿,比绘制一个复杂路径要快得多。这是由于绘制操做发生在 CPU 上,而合成发生在 GPU 上。然而,与这种性质的任何简化同样,潜在的性能提高取决于你的内容。所以,在优化以前测量代码性能是很是重要的,这样你就有比较的基准线了。动画
若是你在多个图层对象上使用同一图像,需本身加载图像并直接将它赋值给图层对象的 contents 属性。给 contents 属性赋值图像可防止图层为后备存储分配内存。相反,图层会使用你提供的图像做为它的后备存储。当几个图层使用同一图像时,这意味着全部图层共享同一内容,而不是它们本身再拷贝图像。ui
为了获得最好结果,你始终应该将你图层对象的宽高设置为整型。虽然你使用单精度数字给图层对象的宽高指定值,但图层边界最终用于建立位图图像。为宽高指定整数值简化了 Core Animation 建立和管理后备存储和其余图层信息必须作的工做。
你在你 delegate 的 drawLayer:inContext:
方法,或者你视图的 drawRect:
方法所作的任何绘制,一般都是在你的 app 主线程同步执行的。然而,在某些状况下,同步绘制你的内容可能不会提供最好的性能。若是你发现你的动画执行效率并非特别好,你应该试着使图层的 drawsAsynchronously
属性生效,去将操做移到后台线程。若是你这样作了,请确保你的代码是线程安全的。而且,你始终应该在将异步绘制代码放到你的项目以前,测量你项目代码性能。
让 Core Animation 决定阴影的形状是很是耗时的,这会影响你 app 的性能。你应该使用CALayer 的 shadowPath 属性显式地指定阴影形状,而不是让 Core Animation 决定阴影的形状。你给该属性指定路径对象时,Core Animation 使用该形状绘制、缓存阴影效果。对于图层的阴影形状尽可能不要改变,这经过减小 Core Animation 的渲染量极大地提升了性能。