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

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

1.cornerRadius

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

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

15060063301952.jpg
15060092904512.jpg

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

// 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();
    // 結(jié)束圖形上下文
    UIGraphicsEndImageContext();
    return image;
}
15060090974778.jpg

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

2.緩存Cell的行高

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

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

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

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

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

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

在你的Cell里面添加一個(gè)這個(gè)方法

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

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末逼庞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子炕檩,更是在濱河造成了極大的恐慌庄撮,老刑警劉巖唯竹,帶你破解...
    沈念sama閱讀 212,686評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沸停,死亡現(xiàn)場(chǎng)離奇詭異辆影,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)后添,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,668評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來薪丁,“玉大人遇西,你說我怎么就攤上這事⊙鲜龋” “怎么了粱檀?”我有些...
    開封第一講書人閱讀 158,160評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)漫玄。 經(jīng)常有香客問我茄蚯,道長(zhǎng)压彭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,736評(píng)論 1 284
  • 正文 為了忘掉前任渗常,我火速辦了婚禮壮不,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘皱碘。我一直安慰自己询一,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,847評(píng)論 6 386
  • 文/花漫 我一把揭開白布癌椿。 她就那樣靜靜地躺著健蕊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪踢俄。 梳的紋絲不亂的頭發(fā)上缩功,一...
    開封第一講書人閱讀 50,043評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音都办,去河邊找鬼嫡锌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛脆丁,可吹牛的內(nèi)容都是我干的世舰。 我是一名探鬼主播,決...
    沈念sama閱讀 39,129評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼槽卫,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼跟压!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起歼培,我...
    開封第一講書人閱讀 37,872評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤震蒋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后躲庄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體查剖,經(jīng)...
    沈念sama閱讀 44,318評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,645評(píng)論 2 327
  • 正文 我和宋清朗相戀三年噪窘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了笋庄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,777評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡倔监,死狀恐怖直砂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浩习,我是刑警寧澤静暂,帶...
    沈念sama閱讀 34,470評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站谱秽,受9級(jí)特大地震影響洽蛀,放射性物質(zhì)發(fā)生泄漏摹迷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,126評(píng)論 3 317
  • 文/蒙蒙 一郊供、第九天 我趴在偏房一處隱蔽的房頂上張望峡碉。 院中可真熱鬧,春花似錦颂碘、人聲如沸异赫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,861評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽塔拳。三九已至,卻和暖如春峡竣,著一層夾襖步出監(jiān)牢的瞬間靠抑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,095評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工适掰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颂碧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,589評(píng)論 2 362
  • 正文 我出身青樓类浪,卻偏偏與公主長(zhǎng)得像载城,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子费就,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,687評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容