UITableView性能優(yōu)化匯總

一. Cell重?用

1. 數(shù)據(jù)源?方法優(yōu)化

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath;

在可?的??會重復繪制??考阱,每次刷新顯示都會去創(chuàng)建新的Cell鞠苟,非常耗費性能乞榨。

解決?案:

?先創(chuàng)建?個靜態(tài)變量reuseID(代理方法返回Cell會調?用很多次当娱,防?重復創(chuàng)建,static保證只會被創(chuàng)建?次态秧,提?性能)扼鞋,然后申鱼,從緩存池中取相應 identifier的Cell并更新數(shù)據(jù),如果沒有淫半,才開始alloc新的Cell,并用identifier標識 Cell科吭。每個Cell都會注冊?個identifier(重用標識符)放?入緩存池猴鲫,當需要調?的時候就直接從緩存池里找對應的id对人,當不需要時就放入緩存池等待調?拂共。(移出屏幕的 Cell才會放?入緩存池中,并不不會被release)所以在數(shù)據(jù)源?法中做出如下

優(yōu)化:

staticNSString*reuseID = “reuseCellID”;// 緩存池中取已經創(chuàng)建的cellUITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:reuseID];

2. 緩存池的實現(xiàn)

當Cell要alloc時势告,UITableView會在堆中開辟?一段內存以供Cell緩存之?用抚恒。Cell的重 ?用通過identifier標識不同類型的Cell咱台,由此可以推斷出俭驮,緩存池外層可能是?個可變字典,通過key來取出內部的Cell混萝,?而緩存池為存儲不同高度、不同類型(包含圖片、 Label等)的Cell雄坪,可以推斷出緩存池的字典內部可能是一個可變數(shù)組,用來存放不不同 類型的Cell维哈,緩存池中只會保存已經被移出屏幕的不同類型的Cell。

3. 緩存池獲取可重用Cell兩個?法的區(qū)別

-(nullable__kindofUITableViewCell*)dequeueReusableCellWithIdentifier: (NSString*)identifier;這個?法會查詢可重?用Cell飘庄,如果注冊了原型Cell购撼,能夠查詢到跪削,否則,返回nil;?且需要判斷if(cell ==nil)晃跺,才會創(chuàng)建Cell毫玖,不推薦-(__kindofUITableViewCell*)dequeueReusableCellWithIdentifier:(NSString*)identifier forIndexPath:(NSIndexPath*)indexPathNS_AVAILABLE_IOS(6_0);使?這個?法之前掀虎,必須通過xib(storyboard)或是Class(純代碼)注冊可重?用 Cell付枫,?而且這個方法?定會返回一個Cell//注冊Cell- (void)registerNib:(nullableUINib*)nib forCellReuseIdentifier:(NSString*)identifierNS_AVAILABLE_IOS(5_0);- (void)registerClass:(nullableClass)cellClass forCellReuseIdentifier:(NSString*)identifierNS_AVAILABLE_IOS(6_0);

好處:

如果緩沖區(qū) Cell 不存在,會使用原型 Cell 實例例化?個新的 Cell二打,不需要再判 斷,同時代碼結構更清晰址儒。

二. 定義?種(盡量少)類型的Cell及善?hidden隱藏(顯示)subviews

1. ?種類型的Cell

分析Cell結構衅疙,盡可能的將 相同內容的抽取到?種樣式Cell中,前?面已經提到了了

Cell的重?機制饱溢,這樣就能保證UITbaleView要顯示多少內容,真正創(chuàng)建出的Cell可能 只比屏幕顯示的Cell多?點绩郎。雖然Cell的’體積’可能會大點,但是因為Cell的數(shù)量量不會很多溉仑,完全可以接受的。

好處:

減少代碼量量浊竟,減少Nib?件的數(shù)量津畸,統(tǒng)?一個Nib?文件定義Cell振定,容易修改肉拓、維護

基于Cell的重?用,真正運?時鋪滿屏幕所需的Cell數(shù)量?致是固定的暖途,設為N個膏执。所 以如果如果只有一種Cell残揉,那就是只有N個Cell的實例;但是如果有M種Cell,那么運行時最多可能會是“M x N = MN”個Cell的實例例抱环,雖然可能并不會占?用太多內存,但是能少點不是更好嗎眶痰。

2. 善用hidden隱藏(顯示)subviews

只定義?種Cell梯啤,那該如何顯示不同類型的內容呢?

答案就是竖伯,把所有不同類型的 view都定義好因宇,放在cell??,通過hidden顯示察滑、隱藏,來顯示不同類型的內容户盯。畢竟饲化,在?戶快速滑動中莽鸭,只是單純的顯示吃靠、隱藏subview比實時創(chuàng)建要快得多。

三. 提前計算并緩存Cell的?高度

在iOS中礁阁,不設UITableViewCell的預估行高的情況下,會優(yōu)先調用 ”tableView:heightForRowAtIndexPath:”?法,獲取每個Cell的即將顯示的高度裂逐, 從而確定UITableView的布局,實際就是要獲取contentSize(UITableView繼承?UIScrollView,只有獲取滾動區(qū)域卜高,才能實現(xiàn)滾動),然后才調用”tableView:cellForRowAtIndexPath”,獲取每個Cell南片,進?賦值庭敦。如果項?中模塊有 10000個Cell需要顯示,可想?知...

解決?案:

我個?認為秧廉,可以創(chuàng)建?個frame模型,提前計算每個Cell的?高度嚼锄。參考其中一篇博客的時候蔽豺,在解決這個問題的時候区丑,可以將計算Cell的?高度放?入數(shù)據(jù)模 型修陡,但這與MVC設計模式可能稍微有點沖突,這個時候我就想到MVVM這種設計模式宴杀,這個時候才能稍微有點MVVM這種設計模式的優(yōu)點(其實還是很不理理解的),可 以講計算Cell?高度放入ViewModel(視圖模型)中婴氮,讓Model(數(shù)據(jù)模型)只負責處理數(shù)據(jù)盾致。

四.異步繪制(自定義Cell繪制)

遇到?較復雜的界?面的時候,如復雜點的圖文混排庭惜,上?的那種優(yōu)化行高的?式可

能就不能滿?要求了,當然了护赊,由于我的開發(fā)經驗尚短,說實話节吮,還沒遇到要將?定義的Cell重新繪制

五.滑動時判耕,按需加載

開發(fā)的過程中自定義Cell的種類千奇百怪透绩,但Cell本來就是?來顯示數(shù)據(jù)的,不說100%帶有圖片碳竟,也差不多,這個時候就要考慮莹桅,下滑的過程中可能會有點卡頓烛亦,尤其網絡不好的時候,異步加載圖片是個程序員都會想到此洲,但是如果給每個循環(huán)對象都加上異步加載,開啟的線程太多呜师,?樣會卡頓,我記得好像線程條數(shù)?般3-5條衷畦,最多也就6條吧。這個時候利利?用UIScrollViewDelegate兩個代理方法就能很好地解決這個問題祈争。

- (void)scrollViewDidEndDragging:(UIScrollView*)scrollView willDecelerate: (BOOL)decelerate- (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView

六.緩存View

當Cell中的部分View是?常獨立的角寸,并且不便于重?的,而且“體積”?常小扁藕,在內存可控的前提下,我們完全可以將這些view緩存起來亿柑。當然也是緩存在模型中。

七.避免?量的圖片縮放疟游、顏?漸變等,盡量顯示“大?剛好合適的圖片資源”

八.避免同步的從網絡颁虐、文件獲取數(shù)據(jù)卧须,Cell內實現(xiàn)的內容來自web瞬痘,使用異步加載板熊,緩存請求結果

九.渲染

1. 減少subviews的個數(shù)和層級

?子控件的層級越深,渲染到屏幕上所需要的計算量量就越大;如多用drawRect繪制元素干签,替代?view顯示

2. 少?用subviews的透明圖層

對于不透明的View拆撼,設置opaque為YES容劳,這樣在繪制該View時闸度,就不需要考慮被View覆蓋的其他內容(盡量設置Cell的view為opaque,避免GPU對Cell下?的內容 也進行繪制)

3. 避免CALayer特效(shadowPath) 給Cell中View加陰影會引起性能問題留量,如下面代碼會導致滾動時有明顯的卡頓:

view.layer.shadowColor = color.CGColor;

view.layer.shadowOffset = offset;

view.layer.shadowOpacity = 1;

view.layer.shadowRadius = radius;

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末哟冬,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子浩峡,更是在濱河造成了極大的恐慌,老刑警劉巖缕粹,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纸淮,死亡現(xiàn)場離奇詭異,居然都是意外死亡萎馅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門飒货,熙熙樓的掌柜王于貴愁眉苦臉地迎上來峭竣,“玉大人塘辅,你說我怎么就攤上這事皆撩≌芤” “怎么了呻惕?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長做院。 經常有香客問我,道長键耕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任屈雄,我火速辦了婚禮官套,結果婚禮上,老公的妹妹穿的比我還像新娘奶赔。我一直安慰自己,他們只是感情好瘸彤,可當我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布笛钝。 她就那樣靜靜地躺著,像睡著了一般玻靡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上囤捻,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天蝎土,我揣著相機與錄音视哑,去河邊找鬼誊涯。 笑死,一個胖子當著我的面吹牛暴构,可吹牛的內容都是我干的段磨。 我是一名探鬼主播耗绿,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼误阻!你這毒婦竟也來了?” 一聲冷哼從身側響起堕绩,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤奴紧,失蹤者是張志新(化名)和其女友劉穎晶丘,沒想到半個月后黍氮,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浅浮,經...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年专执,在試婚紗的時候發(fā)現(xiàn)自己被綠了郁油。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡拄显,死狀恐怖,靈堂內的尸體忽然破棺而出躬审,到底是詐尸還是另有隱情,我是刑警寧澤承边,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站石挂,受9級特大地震影響炒刁,放射性物質發(fā)生泄漏。R本人自食惡果不足惜誊稚,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一翔始、第九天 我趴在偏房一處隱蔽的房頂上張望罗心。 院中可真熱鬧,春花似錦城瞎、人聲如沸渤闷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽飒箭。三九已至,卻和暖如春蜒灰,著一層夾襖步出監(jiān)牢的瞬間弦蹂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工凸椿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人翅溺。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓脑漫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親咙崎。 傳聞我的和親對象是個殘疾皇子优幸,可洞房花燭夜當晚...
    茶點故事閱讀 45,922評論 2 361