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行爲仍是會出現。

相關文章
相關標籤/搜索