国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

UITableView性能優化

2019-11-09 18:00:06
字體:
來源:轉載
供稿:網友

前言

UITableView作為iOS開發中使用最頻繁的控件之一,其性能優化也是常常需要面對的,尤其是當數據量偏大并且設備性能不足時。為了提高程序的穩定性和良好的用戶體驗,UITableView的優化很有必要。

影響性能的主要原因

影響性能的原因有很多種,以下列舉最主要的幾點: 1、 cellForRowAtIndexPath方法中處理了過多的業務。 2、 tableViewCell的SubView層級太復雜,做了大量的透明處理。 3、 cell的height動態變化時計算方法不對。

優化方案

關于影響性能的前兩點比較好理解,此文檔主要針對第三種情況做以處理。想要對tableView做性能優化,只能從tableView的數據源方法入手,而tableView的代理方法中,主要有兩個方法為我們所用:cellForRow和heightForRow。下面我們針對這兩個方法進行深入分析,并給出解決方案。

tableView:heightForRowAtIndexPath

TableView在每次reload data 時都需要所有cell的高度。也就是說如果有100行cell,那么每調用一次reload data ,就會調用100次heightForRowAtIndexPath方法獲取每個cell的高度,而不是說只獲取當前屏幕顯示的cell的高度。對于高度的計算,這里有個小細節需要注意,如果所有cell的高度都固定,那么就刪除代理中的這個tableView:heightForRowAtIndexPath:方法。設置tableView的rowHeight屬性。蘋果的文檔里也介紹了這樣可以減少調用時間。那么對于類似微博、微信朋友圈使用動態的高度,不定數量的文字,可能會有圖片,數量和大小也不固定的情況下,傳統的方法是為cell寫個計算行高的類方法,傳入那些動態的元素(文字,圖片等),然后返回計算后的高度。在tableView:heightForRowAtIndexPath:中調用這個方法,填入需要的參數來計算cell高度。當然這沒有什么問題,而且我們程序里也是這么做的。但是如果計算量很復雜,每次reload Data,光計算行高就花去了rowCount * 單行高的計算時間。假如有100行或更多時,程序里可能不定期的需要reload data 或者insertRow亦或者deleteRow,那么調用時間和內存消耗都很大。

解決辦法:用“空間換時間”

用“空間換時間”簡單說就是將計算行高的時間提前到從服務器返回數據的時候,計算完了行高一并寫入數據庫中。

2. tableView:cellForRowAtIndexPath:

在cellforRow回調的優化上,思路同上,也是通過預處理減少在這個回調中的計算時間。不過,主要針對圖片的異步加載進行優化。 圖片的異步加載無非就是在這個方法里發起異步請求,圖片加載完后根據UIImageView的引用設置圖片。在這里,使用懶加載的方式減少快速滑動時因為網絡請求過于頻繁與切換線程顯示圖片造成卡頓。還有個細節,從服務器拿回來的圖片和最后顯示的大小可能不一樣。這就涉及到對圖片的壓縮。在顯示時,控件加了約束,圖片可能會適應控件大小,圖片變形需要對圖片做transform。每次壓縮圖片都要對圖片乘以一個變換矩陣,如果圖片很多,這個計算量是不容忽視的。

優化建議:

從網絡拿回圖片后,先根據需要顯示的圖片大小切成適合大小的圖,每次只顯示處理過大小的圖片。當查看大圖時再顯示大圖,如果服務器能直接返回預處理好的小圖和圖片的大小更好。

Ps:我們公司的程序里,文件服務器會有多種格式的圖片大小,每次請求時會附帶大小規格,但是,目前文件服務器支持的小圖規格和UI上的控件大小還是不一致,還是會進行壓縮。

圖片壓縮

對于圖片的縮放一般有兩種情況:等比例縮放和直接縮放至指定大小。″等比例縮放 等比例縮放代碼如下(給UIImage添加一個擴展方法)

// 等比縮放

- (UIImage *)hyb_cropEqualScaleImageToSize:(CGSize)size { CGFloat scale = [UIScreen mainScreen].scale; // 這一行至關重要 // 不要直接使用UIGraphicsBeginImageContext(size);方法 // 因為控件的frame與像素是有倍數關系的 // 比如@1x、@2x、@3x圖,因此我們必須要指定scale,否則黃色去不了 // 因為在5以上,scale為2,6plus scale為3,所生成的圖是要合蘋果的 // 規格才能正常 UIGraphicsBeginImageContextWithOptions(size, NO, scale); CGSize aspectFitSize = CGSizeZero; if (self.size.width != 0 && self.size.height != 0) { CGFloat rateWidth = size.width / self.size.width; CGFloat rateHeight = size.height / self.size.height; CGFloat rate = MIN(rateHeight, rateWidth); aspectFitSize = CGSizeMake(self.size.width * rate, self.size.height * rate); } [self drawInRect:CGRectMake(0, 0, aspectFitSize.width, aspectFitSize.height)]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image;}直接縮放至指定大小

// 非等比縮放,生成的圖片可能會被拉伸

- (UIImage *)hyb_cropEqualScaleImageToSize:(CGSize)size { CGFloat scale = [UIScreen mainScreen].scale; UIGraphicsBeginImageContextWithOptions(size, NO, scale); [self drawInRect:CGRectMake(0, 0, size.width, size.height)]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }

聲明:本文部分內容參考于編程小翁和標哥博客。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 德安县| 古田县| 鹤山市| 洪湖市| 崇义县| 霍邱县| 平陆县| 策勒县| 金寨县| 胶南市| 米脂县| 泰顺县| 佛冈县| 宣威市| 鄂尔多斯市| 丰原市| 新建县| 宁海县| 博客| 泽库县| 宽甸| 丘北县| 南充市| 金溪县| 安远县| 綦江县| 高密市| 乐业县| 梁山县| 调兵山市| 大洼县| 遂溪县| 获嘉县| 搜索| 安新县| 青铜峡市| 江川县| 东乡| 武冈市| 正蓝旗| 贡嘎县|