UITableView表格性能優(yōu)化(一)

作為一名iOS開發(fā)程序員,你肯定能寫出TableView..但是這個TableView的性能到底怎么樣呢...那就那就仁者見仁智者見智了..
網(wǎng)上的文章一抄一大把.在這里作為一個彩筆的我...也給幾條建議吧...

1.cornerRadius

imageView.layer.cornerRadius = 10;
imageView.clipsToBounds = YES;

相信小伙伴們對cornerRaius并不陌生,如果在iOS8之前,在表格視圖中如果頻繁大量使用cornerRaius,就可能會對表格的性能產生影響...

15060063301952.jpg
15060092904512.jpg

你會發(fā)現(xiàn),視圖中用了cornerRaius的部分是紅色的...
可能單單這樣一個視圖沒什么問題,但是如果在tableView中會怎么樣...
在每個單元格中可能就會對性能產生一定的影響了...
為什么會影響呢?是因為蘋果對裁切做了透明效果的處理,混合模式變紅就是一個很好的說明,而這個alpha可能會對性能造成影響...
但是據(jù)說iOS8之后蘋果對cornerRaius做了優(yōu)化,理論上說對性能的影響降低了....
但是還是感覺很不爽啊....
所以咱們還是自己開啟圖形上下文自己畫把....
自己動手豐衣足食....

// UIImage 分類方法
- (instancetype)jb_circleImage {
    // 開啟圖形上下文   opaque 一定要寫YES 表示不透明
    UIGraphicsBeginImageContextWithOptions(self.size, YES, 0);
    // 范圍
    CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);  
    // 填充顏色<這里的顏色就你來定拉~~>
    [[UIColor whiteColor] setFill];
    UIRectFill(rect);
    // 裁剪
    [[UIBezierPath bezierPathWithOvalInRect:rect] addClip];
    // 繪制圖片到圓上面
    [self drawInRect:rect];
    // 獲得圖片
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    // 結束圖形上下文
    UIGraphicsEndImageContext();
    return image;
}
15060090974778.jpg

親愛的小伙伴,是不是看到綠色就舒服多了....
如果你說反正也這個顏色也不在頭上我也沒辦法...
誰讓它不是王寶綠呢...
上面那個分類方法我是用貝塞爾路徑切的,如果用上下文切也是可以的,調用CGContextClip(context)這個小函數(shù),不過要多獲取一下上下文~

2.緩存Cell的行高

各位小伙伴,如果你遇到Cell高度不同的時候是怎么處理的呢,相信老程序員們都還記得木有自動布局的那一段用frame計算行高的輕松的時刻....
而后來,我們有了AutoLayout,僅僅是因為蘋果的機型變多了,從iPhone4,5,6,6+,iPadAir,Pro....
各種各樣的機型層出不窮,為了適配我們不得不選擇更為牛X的AutoLayout...
最開始我們用Autoresizing,然后蘋果讓我們用原生的那一長串布局,然后蘋果發(fā)現(xiàn)那一串真的很長,于是出了VFL,然后發(fā)現(xiàn)VFL不太友好,又出了LayoutAnchors,但是最后我們選擇了Masonry/SnapKit.....
大部分小伙伴還是用Masonry的....吧.....
雖然不更新了.....
其實用Masonry真的是非常的簡單加方便,相信用過的小伙伴們都會說好....
But用自動布局來計算行高真的真的是非常消耗CPU,因為表格發(fā)生滾動行高就要進行計算,這是和之前用frame來計算行高是截然不同的,別看你只寫了兩句話(貌似第二句也不用寫了,那么就一句話)...

self.tableView.estimatedRowHeight = 100;
self.tableView.rowHeight = UITableViewAutomaticDimension;

系統(tǒng)在后臺要一直幫你拼命的計算行高啊啊啊啊啊!!!!!!
然后稍微不注意就會出現(xiàn)控制臺發(fā)生警告,那一坨坨是不是看了都想死....
不過沒關系,那個只要調整一下最后一條和contentView的約束的優(yōu)先級<調低一點>(或者瘋狂的用lessThan,greaterThan)就OK了...扯遠了...
我們的話題是!!這樣很消耗CPU啊啊啊啊.....
你想想:用戶正在用你的APP滾動表格,也許他就是想瀏覽一下,就那么滾啊滾,結果電量掉的嗖嗖的,手機還發(fā)燙,那么你說你親愛的用戶會干嘛?給你打個電話?告訴你:親愛的,你的表格滾起來有點燙手哦~~~~~~呵呵呵呵呵,碰到傲嬌一點的就直接給你卸載了好不好....
好吧..扯了這么多沒用的那么我們來說說解決辦法吧...
那就是:緩存行高..
tableView有這么一個代理方法:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

默認的情況下每個Cell會調用3次(貌似Xcode版本不一樣這個值也不盡相同),是不是很驚悚,假如每個Cell都用自動布局,每個Cell系統(tǒng)都要忙碌的計算三次,表格能不卡嗎.....
它的原理是這樣的:
1.假如你沒有設置預估行高呢,每個Cell都先計算一次,然后再計算你顯示行的高度,一直到Cell能夠填滿你目前的屏幕,同時更新contentSize這樣你就能滾了,哦,不..你的表格又能愉快的滾動了...
2.如果你設置了預估行高呢,那么系統(tǒng)會根據(jù)你設置的預估行高計算一下contentSize;至于你計算多少次也是根據(jù)你設置的預估行高來的,直到填滿你的手機屏幕,更新contentSize;你要是給太大的預估行高,超出了預估的范圍,她會順序的計算后面的行高,一直到填滿屏幕...
3.怎么說呢,使用預估行高在每個Cell的顯示之前都需要計算,所以單個Cell的效率略低,但是整體的效率提高了啊.....
4.所以預估行高你別瞎給,盡量給的稍微準點....

言歸正傳.要怎么做呢
在這里我介紹兩個方法
方法一: 用別人寫好的第三方庫,至于用什么就自行去谷歌或者GitHub上面搜索吧
方法二: 自己緩存.
如果你用MVC開發(fā)呢,就在你的模型屬性中定義一個專門用來存儲行高的屬性,如果你用MVVM開發(fā)呢,那么就在你的視圖模型中定義一個存儲行高的屬性(貌似我是在寫廢話......)
然后你再heightForRowAtIndexPath那個方法里面創(chuàng)建一個Cell<一定要用alloc/init創(chuàng)建,從緩存池中取會造成死循環(huán),至于為什么自己去想!!!>,然后你把你的模型數(shù)據(jù)賦值給它,然后重頭戲來了你要調用一下這個方法:[self layoutIfNeeded];從而Cell提前計算約束!提前計算約束!提前計算約束!
有了約束你就能獲得最大的Y了,有了最大的Y,行高就緩存上了

在你的Cell里面添加一個這個方法

- (CGFloat)calculateRowHeight:(XXModel *)yourModel {
    self.model = yourModel;
    
    [self.view layoutIfNeeded];
    
    return CGRectGetMaxY(你最下面控件.frame);
}

最后你再heightForRowAtIndexPath里面返回的行高就是你計算出來的行高了,這樣只用計算一次就可以了,并且還作為屬性緩存起來,大大節(jié)省了CPU的開銷....

最后的最后......假如你是ibireme的粉絲的話,他的一篇文章可以拜讀一下,好吧我承認寫的比我深刻多了........https://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容