CPU資源消耗的原因和解決方案
對象創建
*輕量對象代替重量對象
* 不需要響應觸摸事件的控件:CALayer顯示
* 對象不涉及UI操作,則盡量放到后臺線程創建
* 包含有CALayer的控件只能在主線程創建和操作
* 通過Storyboard 創建視圖對象時,其資源消耗會比直接通過代碼創建對象要大非常多,在性能敏感的界面里,storyboard不是一個好的技術選擇
* 盡量推遲對象創建的時間,并把對象的創建分散到多個任務中去。
* 對象的復用代價比釋放,創建新對象要小,這類對象應當盡量放到一個緩存池里復用
對象調整
* CALayer:CALayer內部并沒有屬性,當調用屬性方法時,它內部是通過運行時resolveInstanceMethod為對象臨時添加一個方法,并把對應屬性值保存到內部的一個Dictionary里,同時還會通知delegate,創建動畫等等,非常消耗資源。
* UIView的關于顯示相關的屬性(frame/bound/transform)等實際上都是CALayer屬性映射來的,所以對UIView的這些屬性進行調整時,消耗的資源要遠大于一般的屬性,所以,盡量減少不必要的屬性修改
* 當視圖層次調整時,UIView,CALayer之間會出現很多方法調用與通知,所以,應盡量避免調整視圖層次,添加和移除視圖。
對象銷毀
把對象捕獲到block中,然后扔到后臺隊列去隨便發送個消息以避免編譯器警告,就可以讓對象在后臺線程銷毀了。
布局計算
* 視圖布局的計算是App中最為常見的消耗CPU資源的地方
* 在后臺線程提前計算好視圖布局,并且對視圖布局進行緩存
* 用任何技術對視圖進行布局,最終都會落到對UIView.frame/bounds/center等屬性的調整上 對象調整:非常消耗資源,所以盡量提前計算好布局,在需要時一次性調整好對應屬性,而不要多次,頻繁的計算和調整這些屬性。
Autolayout
不手動調整frame 等屬性,可以用常見的快捷屬性:left/right/top/bottom/width/height,或使用ComponentKit,AsyncDisplayKit等框架
文本渲染
* 所有的文本內容控件,在底層都是通過CoreText排版,繪制為Bitmap顯示的。
* 常見的文本控件(UILabel,UITextView),其排版和繪制都是在主線程進行的,當顯示大量文本時,CPU的壓力會非常大。
* 解決方案:自定義文本控件,用TextKit或底層的CoreText對文本異步繪制
* CoreText對象創建好后,能直接獲取文本的寬高信息,避免了多次計算(調整UILabel大小時算一遍,UILabel繪制時內部再算一遍),CoreText對象占用內存較少,可以緩存下來供稍后多次渲染。
圖片的解碼
* 用UIImage 或CGImageSource創建圖片時,圖片數據不會立刻解碼。圖片設置到UIImageView或者CALayer.contents中去,并且CALayer被提交到GPU前,CGImage中的數據才會得到解碼。 _發生在主線程,不可避免。
* 后臺線程先把圖片會知道CGBitmapContext中,然后從Bitmap直接創建圖片。
圖像的繪制
* 圖像繪制:以CG開頭的方法把圖像繪制到畫布中,然后從畫布創建圖片并顯示 如:[UIView drawRect:]
* CoreGraphic 方法通常是線程安全的,圖像的繪制可以放到后臺線程進行
GPU 資源消耗原因和解決方案
GPU:接收提交的紋理和頂點描述(三角形),應用變換(transform),混合并渲染,然后輸出到屏幕上。
所看到的內容:紋理和形狀(三角形模擬的矢量圖形)
紋理的渲染
* 所有的Bitmap ,包括圖片,文本,柵格化的內容,最終都要由內存提交到顯存,綁定為GPU Texture.
* 提交到顯存的過程,GPU調整和渲染Texture的過程,都要消耗不少GPU資源
* 當在較短時間顯示大量圖片(TableView存在非常多的圖片并且快速滑動時),CPU占有率很低,GPU占有非常高,界面仍然會掉幀。
* 盡量減少在短時間內大量圖片的顯示,盡可能將多張圖片合成為一張進行顯示。
* 圖片過大,超過GPU的最大紋理尺寸時,圖片需要先由CPU進行預處理,這對CPU和GPU都會帶來額外的資源消耗。iPhone4S以上機型,紋理尺寸上限4096*4096
視圖的混合
* 當多個視圖(CALayer)重疊在一起顯示時,GPU會首先把他們混合到一起。如果視圖結構過于復雜,混合的過程也會消耗很多GPU資源。
* 應用應當盡量減少視圖數量和層次,并在不透明的視圖里標明opaque屬性以避免無用的Alpha通道合成。
* 把多個視圖預先渲染為一張圖片來顯示。
圖形的生成
* CALayer的border,圓角,陰影,遮罩(mask),CASharpLayer的矢量圖形顯示,通常會觸發離屏渲染(offscreen rendering),而離屏渲染通暢發生在GPU中。
* 當一個列表視圖中出現大量圓角的CALayer,并且快速滑動時,可以觀察到GPU資源已經占滿,而CPU資源消耗很少。界面仍然能正?;瑒?,但平均幀數會降到很低
* 避免這種情況,可以嘗試開啟CALayer.shouldRasterize(柵格化)屬性,但這會把原本離屏渲染的操作轉嫁到CPU上去。
* 圓角圖片遮擋
* 把需要顯示的圖形在后臺線程繪制為圖片,避免使用圓角,陰影,遮罩等屬性。
-
cpu
+關注
關注
68文章
10854瀏覽量
211589
原文標題:iOS構建流暢的交互界面—CPU,GPU資源消耗的原因和解決方案
文章出處:【微信號:Imgtec,微信公眾號:Imagination Tech】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論