UITalbeView作為一個專案中常用的開發元件之一,如何讓其保持流暢的滑動則是最重要的一個環節。
UITableView的核心思想為cell的重用機制。簡單的理解就是將滑出螢幕外的cell放進重用池,當要顯示某一位置的cell時,先去檢查重用池中是否有可重用的cell,如果有,就直接拿來顯示;如果沒有,才會建立。這樣做的好處可想而知,極大的減少了記憶體的開銷。
然而重用cell只是優化UITableView的基礎。
病因
App 主執行緒開始在 CPU 中計算顯示內容,比如檢視的建立、佈局計算、圖片解碼、文字繪製等。隨後 CPU 會將計算好的內容提交到 GPU 去,由 GPU 進行變換、渲染等一系列的處理。隨後 GPU 會把渲染結果提交到幀緩衝區去,等待顯示到螢幕上。由於垂直同步的機制,如果一定的時間內,CPU 或者 GPU 沒有完成內容提交,則那一幀就會被丟棄,等待下一次機會再顯示,而這時螢幕會保留之前的內容不變。這就是介面卡頓的原因。
佔用資源主要原因及解決方案
1、控制元件的建立
在tableView中肯定有大量的內容需要進行展示,所以在cell中肯定需要建立大量的UIView、UILabel之類的控制元件,在建立時就需要分配記憶體、調整屬性,這些操作都是比較消耗CPU資源的。
在cellForRowAtIndexPath中不要出現建立物件的程式碼,儘量在cell初始化的時候建立好所有的控制元件。儘量使用更為輕量的CALayer來代替UIView。
2、檢視佈局的計算
檢視佈局的計算是吃CPU資源的主要原因之一,因為計算,所以這方面的資源佔用率就不可避免了。
雖然是不可避免的,但也需要將佔用資源比例降低。
不論通過何種技術對檢視進行佈局,其最終都會落到對 frame等屬性的調整上。對這些屬性的調整非常消耗資源,所以儘量提前計算好佈局,在需要時一次性調整好對應屬性,而不要頻繁的計算和調整這些屬性。
3、文字的計算
上面說了只要有計算,對資源的佔用就不可避免,所以將文字寬高的計算放入子執行緒操作,會給主執行緒減少相當一部分的空間。
4、影象的繪製與圖形的生成
drawRect對資源的佔用大家應該都有所瞭解,因CoreGraphic 方法通常都是執行緒安全的,所以影象的繪製可以很容易的放到後臺執行緒進行。
在專案中經常會把頭像之類的控制元件設定成圓角,如果我們操作CALayer的屬性通常都會觸發離屏渲染,而當一個介面中出現大量的圓角影象時,滑動幀率就會降得很低。所以儘量避免使用CALayer來生成圓角屬性。設定圓角可以參考:iOS 高效新增圓角效果實戰講解
優化技巧
預排版
從後臺的回撥中拿到資料時,通過後臺執行緒將所有控制元件的高度與cell的整體高度都給計算出來,然後將這些計算出來的高度都給快取起來。
高度返回
若高度一定,直接使用rowHeight屬性而不是使用heightForRowAtIndexPath方法,以減少呼叫的消耗。
圖片設定
在設定顯示圖片時,不要直接設定UIImageView的contentMode屬性自動適應,圖片變形會計算transform,壓縮時會乘以一個矩陣,消耗效能。對於要求效能較高的app,應該將得到的圖片經過處理成UIImageView大小後再呈現。