前言


核心动画是提高基于APP动画帧率的好方式,但是核心动画的使用不代表性能的提升的保证。尤其在OSX,当使用核心动画时,我们仍需选择最有效的方式。和所有的性能相关的问题一样,我们应该使用工具时时的评估和跟踪APP的性能,以至于我们能够确保性能是提升而不是退化的。

 

综合的建议和技巧


有以下几种方式能让我们的Layers更有效的实现效果。对于任何优化来说,我们应该在尝试优化前先测量当前代码的性能;根据未优化之前的性能检测结果,能够让我们知道所做的优化是否提升了性能。

 

尽可能的使用不透明的Layers


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

  • 作为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频繁改变(它将会被频繁重绘),大量的时间花费在绘制上就会变成性能瓶颈。

为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开辟新的内存。

 

保证设置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行为还是会出现。

Core Animation 文档翻译 (第八篇)—提高动画的性能的更多相关文章

  1. Core Animation 文档翻译 (第一篇)

    Core Animation 文档翻译(第一篇)   2018-01-13  星期6 前言:作为iOS 开发,官方文档的阅读是很有必要的,值此周末便写下此文.作为iOS 实际经验3年的开发,之前的应用 ...

  2. Core Animation文档翻译 (第一篇)

    Core Animation 文档翻译(第一篇) 前言 作为iOS 开发,官方文档的阅读是很有必要的,值此周末便写下此文.作为iOS 实际经验3年的开发,之前有阅读并实践过经典的<iOS核心动画 ...

  3. Core Animation 文档翻译 (第二篇)

    Core Animation 文档翻译 (第二篇) 核心动画基础要素 核心动画为我们APP内Views动画和其他可视化元素动画提供了综合性的实现体系.核心动画不是我们APP内Views的替代品,相反, ...

  4. Core Animation 文档翻译—附录B(可动画的属性)

    前言   许多CALayer和CIFliter的属性都是可动画的.本节附录列出了这些属性默认使用的动画.   CALayer可动画属性   表B-1展示了CALayer类的可动画属性.针对每个属性此表 ...

  5. Core Animation 文档翻译 (第七篇)——改变Layer的默认动画

    前言 核心动画使用action对象实现它的可视化动画.一个action对象是指遵循CAAction协议并定义了Layer相关的动画行为的对象.所有的CAAnimation对象实现了这个协议,无论何时L ...

  6. Core Animation 文档翻译(第三篇)

    Core Animation 文档翻译(第三篇) 设置Layer对象 当我们使用核心动画时,Layer对象是一切的核心.Layers 管理我们APP的可视化content,Layer也提供了conte ...

  7. Core Animation 文档翻译 (第六篇)

      高级动画技巧 配置属性动画或者关键帧动画的方式是多种多样的.需要同时执行多个动画或者顺序执行多个动画的APP,可以通过高级的方式同步这些动画的timing或者将这些动画绑定在一起.我们也可以使用其 ...

  8. Core Animation 文档翻译 (第四篇)

    Core Animation 文档翻译(第四篇) 让Layer的content动画起来 核心动画的基础接口以及为拥有Layer的View做的动画扩展接口,使得为Layer制作复杂动画变得简单化.例如改 ...

  9. Core Animation 文档翻译 (第五篇)

      构建Layer层次结构 在APP中大多数情况下,将Layer和View对象结合使用是Layer最好的使用方式.然而,很多时候我们可能需要通过添加单独的Layer对象,以便增加视图继承层次:当为了提 ...

随机推荐

  1. MySQL常用查询语句汇总(不定时更新)

    在这篇文章中我会通过一些例子来介绍日常编程中常用的SQL语句   目录: ## 1.数据库的建立     ## 1.数据库的建立   实例将ER图的形式给出:   由此转换的4个关系模式:      ...

  2. deeplearning.ai 构建机器学习项目 Week 1 机器学习策略 I 听课笔记

    这门课是讲一些分析机器学习问题的方法,如何更快速高效的优化机器学习系统,以及NG自己的工程经验和教训. 1. 正交化(Othogonalization) 设计机器学习系统时需要面对一个问题是:可以尝试 ...

  3. (亲测)1分钟破解IDM权限,傻瓜都能学会的破解方法(番外篇:利用破解工具直接破解IDM)

    Internet Download Manager (IDM)是比较好用的一款下载工具~ 上一节我讲到一种利用修改防火墙来进行阻止访问服务器,请参看这篇文章(亲测)躺着破解IDM下载权限,治疗不用破解 ...

  4. 51nod 1575 Gcd and Lcm

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1575 万年巨坑终于填掉了…… 首先是煞笔西瓜的做题历程O_O. ...

  5. bzoj:1723: [Usaco2009 Feb]The Leprechaun 寻宝

    Description 你难以想象贝茜看到一只妖精在牧场出现时是多么的惊讶.她不是傻瓜,立即猛扑过去,用她那灵活的牛蹄抓住了那只妖精.     “你可以许一个愿望,傻大个儿!”妖精说.     “财富 ...

  6. Prim最小生成树板子

    普里姆算法可以称为"加点法",每次迭代选择代价最小的边对应的点,加入到最小生成树中.算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点. 邻接矩阵存图  时间复杂度O(n^2 ...

  7. c++中的overload、overwrite、override

    作为初学者,本文只从语法和简单的使用角度对overload.overwrite.override进行了区分,不曾涉及原理,记录下来以供查阅. 1.verload(重载) 1.1 基本要求: c++中的 ...

  8. UEP-时间

    时间戳转化为Date(or String) SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ...

  9. 【CC2530入门教程-增强版】基础技能综合实训案例(基础版)-上位机源码

    [CC2530入门教程-增强版]基础技能综合实训案例(基础版)-上位机源码 广东职业技术学院  欧浩源 一.需求分析 按照指定参数打开串口,与测控终端建立数据传输通道,并根据应用要求实现程序逻辑,具体 ...

  10. tp5命名空间