對基於 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 的渲染量極大地提升了性能。