下列內容爲閱讀文章的摘錄,原文連接:http://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/ios
CPU資源消耗緩存
一、對象建立安全
經過 Storyboard 建立視圖對象時,其資源消耗會比直接經過代碼建立對象要大很是多網絡
二、對象建立異步
UIView 的關於顯示相關的屬性(好比 frame/bounds/transform)等實際上都是 CALayer 屬性映射來的,因此對 UIView 的這些屬性進行調整時,消耗的資源要遠大於通常的屬性async
當視圖層次調整時,UIView、CALayer 之間會出現不少方法調用與通知,因此在優化性能時,應該儘可能避免調整視圖層次、添加和移除視圖佈局
三、對象銷燬性能
這裏有個小 Tip:把對象捕獲到 block 中,而後扔到後臺隊列去隨便發送個消息以免編譯器警告,就可讓對象在後臺線程銷燬了。優化
NSArray *tmp = self.array;
self.array = nil;
dispatch_async(queue, ^{
[tmp class];
});
四、佈局計算spa
其最終都會落到對 UIView.frame/bounds/center 等屬性的調整上。上面也說過,對這些屬性的調整很是消耗資源,因此儘可能提早計算好佈局,在須要時一次性調整好對應屬性,而不要屢次、頻繁的計算和調整這些屬性。
五、文本計算
若是你對文本顯示沒有特殊要求,能夠參考下 UILabel 內部的實現方式:用 [NSAttributedString boundingRectWithSize:options:context:] 來計算文本寬高,用 -[NSAttributedString drawWithRect:options:context:] 來繪製文本。儘管這兩個方法性能不錯,但仍舊須要放到後臺線程進行以免阻塞主線程。
若是你用 CoreText 繪製文本,那就能夠先生成 CoreText 排版對象,而後本身計算了,而且 CoreText 對象還能保留以供稍後繪製使用。
六、文本渲染
屏幕上能看到的全部文本內容控件,包括 UIWebView,在底層都是經過 CoreText 排版、繪製爲 Bitmap 顯示的。
CoreText 對象建立好後,能直接獲取文本的寬高等信息,避免了屢次計算(調整 UILabel 大小時算一遍、UILabel 繪製時內部再算一遍);CoreText 對象佔用內存較少,能夠緩存下來以備稍後屢次渲染
七、圖片解碼
當你用 UIImage 或 CGImageSource 的那幾個方法建立圖片時,圖片數據並不會馬上解碼。圖片設置到 UIImageView 或者 CALayer.contents 中去,而且 CALayer 被提交到 GPU 前,CGImage 中的數據纔會獲得解碼。這一步是發生在主線程的,而且不可避免。若是想要繞開這個機制,常見的作法是在後臺線程先把圖片繪製到 CGBitmapContext 中,而後從 Bitmap 直接建立圖片。目前常見的網絡圖片庫都自帶這個功能。
八、圖片繪製
圖像的繪製一般是指用那些以 CG 開頭的方法把圖像繪製到畫布中,而後從畫布建立圖片並顯示這樣一個過程。這個最多見的地方就是 [UIView drawRect:] 裏面了。因爲 CoreGraphic 方法一般都是線程安全的,因此圖像的繪製能夠很容易的放到後臺線程進行。一個簡單異步繪製的過程大體以下(實際狀況會比這個複雜得多,但原理基本一致):
- (void)display {
dispatch_async(backgroundQueue, ^{
CGContextRef ctx = CGBitmapContextCreate(...);
// draw in context...
CGImageRef img = CGBitmapContextCreateImage(ctx);
CFRelease(ctx);
dispatch_async(mainQueue, ^{
layer.contents = img;
});
});
}
爲了減輕這種狀況的 GPU 消耗,應用應當儘可能減小視圖數量和層次,並在不透明的視圖裏標明 opaque 屬性以免無用的 Alpha 通道合成。
CALayer 的 border、圓角、陰影、遮罩(mask),CASharpLayer 的矢量圖形顯示,一般會觸發離屏渲染(offscreen rendering),而離屏渲染一般發生在 GPU 中。當一個列表視圖中出現大量圓角的 CALayer,而且快速滑動時,能夠觀察到 GPU 資源已經佔滿,而 CPU 資源消耗不多。
這時界面仍然能正常滑動,但平均幀數會降到很低。爲了不這種狀況,能夠啓用CALayer的shouldRasterize 屬性,但這會把本來離屏渲染的操做轉移到 CPU 上去。
對於只須要圓角的某些場合,也能夠用一張已經繪製好的圓角圖片覆蓋到本來視圖上面來模擬相同的視覺效果。最完全的解決辦法,就是把須要顯示的圖形在後臺線程繪製爲圖片,避免使用圓角、陰影、遮罩等屬性。