三年iOS開發(fā)在開發(fā)中都要用到的技術(shù)映砖,超實(shí)用!

1.?Cell重用

1.1>數(shù)據(jù)源方法優(yōu)化

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

在可見的頁面會(huì)重復(fù)繪制頁面面粮,每次刷新顯示都會(huì)去創(chuàng)建新的Cell少孝,非常耗費(fèi)性能。

解決方案:首先創(chuàng)建一個(gè)靜態(tài)變量reuseID(代理方法返回Cell會(huì)調(diào)用很多次熬苍,防止重復(fù)創(chuàng)建稍走,static保證只會(huì)被創(chuàng)建一次,提高性能)柴底,然后婿脸,從緩存池中取相應(yīng)identifier的Cell并更新數(shù)據(jù),如果沒有柄驻,才開始alloc新的Cell狐树,并用identifier標(biāo)識(shí)Cell。每個(gè)Cell都會(huì)注冊(cè)一個(gè)identifier(重用標(biāo)識(shí)符)放入緩存池鸿脓,當(dāng)需要調(diào)用的時(shí)候就直接從緩存池里找對(duì)應(yīng)的id褪迟,當(dāng)不需要時(shí)就放入緩存池等待調(diào)用冗恨。(移出屏幕的Cell才會(huì)放入緩存池中,并不會(huì)被release)所以在數(shù)據(jù)源方法中做出如下優(yōu)化:

//?調(diào)用次數(shù)太多味赃,static?保證只創(chuàng)建一次reuseID掀抹,提高性能

static?NSString?*reuseID?=?“reuseCellID”;

//?緩存池中取已經(jīng)創(chuàng)建的cell

UITableViewCell?*cell?=?[tableView?dequeueReusableCellWithIdentifier:reuseID];

1.2>緩存池的實(shí)現(xiàn)

當(dāng)Cell要alloc時(shí),UITableView會(huì)在堆中開辟一段內(nèi)存以供Cell緩存之用心俗。Cell的重用通過identifier標(biāo)識(shí)不同類型的Cell傲武,由此可以推斷出,緩存池外層可能是一個(gè)可變字典城榛,通過key來取出內(nèi)部的Cell揪利,而緩存池為存儲(chǔ)不同高度、不同類型(包含圖片狠持、Label等)的Cell疟位,可以推斷出緩存池的字典內(nèi)部可能是一個(gè)可變數(shù)組,用來存放不同類型的Cell喘垂,緩存池中只會(huì)保存已經(jīng)被移出屏幕的不同類型的Cell甜刻。

1.3>緩存池獲取可重用Cell兩個(gè)方法的區(qū)別

-(nullable?__kindof?UITableViewCell?*)dequeueReusableCellWithIdentifier:(NSString?*)identifier;

這個(gè)方法會(huì)查詢可重用Cell,如果注冊(cè)了原型Cell正勒,能夠查詢到得院,否則,返回nil章贞;而且需要判斷if(cell?==?nil)祥绞,才會(huì)創(chuàng)建Cell,不推薦

-(__kindof?UITableViewCell?*)dequeueReusableCellWithIdentifier:(NSString?*)identifier?forIndexPath:(NSIndexPath?*)indexPath?NS_AVAILABLE_IOS(6_0);

使用這個(gè)方法之前鸭限,必須通過xib(storyboard)或是Class(純代碼)注冊(cè)可重用Cell蜕径,而且這個(gè)方法一定會(huì)返回一個(gè)Cell

注冊(cè)Cell

-?(void)registerNib:(nullable?UINib?*)nib?forCellReuseIdentifier:(NSString?*)identifier?NS_AVAILABLE_IOS(5_0);

-?(void)registerClass:(nullable?Class)cellClass?forCellReuseIdentifier:(NSString?*)identifier?NS_AVAILABLE_IOS(6_0);

好處:如果緩沖區(qū)?Cell?不存在,會(huì)使用原型?Cell?實(shí)例化一個(gè)新的?Cell败京,不需要再判斷丧荐,同時(shí)代碼結(jié)構(gòu)更清晰阔籽。

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

2.1>一種類型的Cell

分析Cell結(jié)構(gòu)未斑,盡可能的將?相同內(nèi)容的抽取到一種樣式Cell中悠鞍,前面已經(jīng)提到了Cell的重用機(jī)制,這樣就能保證UITbaleView要顯示多少內(nèi)容隧甚,真正創(chuàng)建出的Cell可能只比屏幕顯示的Cell多一點(diǎn)。雖然Cell的’體積’可能會(huì)大點(diǎn)渡冻,但是因?yàn)镃ell的數(shù)量不會(huì)很多戚扳,完全可以接受的。好處:

*?減少代碼量族吻,減少Nib文件的數(shù)量帽借,統(tǒng)一一個(gè)Nib文件定義Cell珠增,容易修改、維護(hù)

*?基于Cell的重用砍艾,真正運(yùn)行時(shí)鋪滿屏幕所需的Cell數(shù)量大致是固定的蒂教,設(shè)為N個(gè)。所以如果如果只有一種Cell脆荷,那就是只有N個(gè)Cell的實(shí)例凝垛;但是如果有M種Cell,那么運(yùn)行時(shí)最多可能會(huì)是“M?x?N?=?MN”個(gè)Cell的實(shí)例蜓谋,雖然可能并不會(huì)占用太多內(nèi)存梦皮,但是能少點(diǎn)不是更好嗎。

2.2>善用hidden隱藏(顯示)subviews

只定義一種Cell桃焕,那該如何顯示不同類型的內(nèi)容呢剑肯?答案就是,把所有不同類型的view都定義好观堂,放在cell里面让网,通過hidden顯示、隱藏型将,來顯示不同類型的內(nèi)容寂祥。畢竟,在用戶快速滑動(dòng)中七兜,只是單純的顯示丸凭、隱藏subview比實(shí)時(shí)創(chuàng)建要快得多。

3.?提前計(jì)算并緩存Cell的高度

在iOS中腕铸,不設(shè)UITableViewCell的預(yù)估行高的情況下惜犀,會(huì)優(yōu)先調(diào)用”tableView:heightForRowAtIndexPath:”方法,獲取每個(gè)Cell的即將顯示的高度狠裹,從而確定UITableView的布局虽界,實(shí)際就是要獲取contentSize(UITableView繼承自UIScrollView,只有獲取滾動(dòng)區(qū)域,才能實(shí)現(xiàn)滾動(dòng)),然后才調(diào)用”tableView:cellForRowAtIndexPath”,獲取每個(gè)Cell涛菠,進(jìn)行賦值莉御。如果項(xiàng)目中模塊有10000個(gè)Cell需要顯示,可想而知…

解決方案:我個(gè)人認(rèn)為俗冻,可以創(chuàng)建一個(gè)frame模型礁叔,提前計(jì)算每個(gè)Cell的高度。參考其中一篇博客的時(shí)候迄薄,在解決這個(gè)問題的時(shí)候琅关,可以將計(jì)算Cell的高度放入數(shù)據(jù)模型,但這與MVC設(shè)計(jì)模式可能稍微有點(diǎn)沖突讥蔽,這個(gè)時(shí)候我就想到MVVM這種設(shè)計(jì)模式涣易,這個(gè)時(shí)候才能稍微有點(diǎn)MVVM這種設(shè)計(jì)模式的優(yōu)點(diǎn)(其實(shí)還是很不理解的)画机,可以講計(jì)算Cell高度放入ViewModel(視圖模型)中,讓Model(數(shù)據(jù)模型)只負(fù)責(zé)處理數(shù)據(jù)新症。

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

遇到比較復(fù)雜的界面的時(shí)候步氏,如復(fù)雜點(diǎn)的圖文混排,上面的那種優(yōu)化行高的方式可能就不能滿足要求了账劲,當(dāng)然了戳护,由于我的開發(fā)經(jīng)驗(yàn)尚短,說實(shí)話瀑焦,還沒遇到要將自定義的Cell重新繪制

5.滑動(dòng)時(shí)腌且,按需加載

開發(fā)的過程中,自定義Cell的種類千奇百怪榛瓮,但Cell本來就是用來顯示數(shù)據(jù)的铺董,不說100%帶有圖片,也差不多禀晓,這個(gè)時(shí)候就要考慮精续,下滑的過程中可能會(huì)有點(diǎn)卡頓,尤其網(wǎng)絡(luò)不好的時(shí)候粹懒,異步加載圖片是個(gè)程序員都會(huì)想到重付,但是如果給每個(gè)循環(huán)對(duì)象都加上異步加載,開啟的線程太多凫乖,一樣會(huì)卡頓确垫,我記得好像線程條數(shù)一般3-5條,最多也就6條吧帽芽。這個(gè)時(shí)候利用UIScrollViewDelegate兩個(gè)代理方法就能很好地解決這個(gè)問題删掀。

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

-?(void)scrollViewDidEndDecelerating:(UIScrollView?*)scrollView

6.緩存View

當(dāng)Cell中的部分View是非常獨(dú)立的,并且不便于重用的导街,而且“體積”非常小披泪,在內(nèi)存可控的前提下,我們完全可以將這些view緩存起來搬瑰。當(dāng)然也是緩存在模型中款票。

7.避免大量的圖片縮放、顏色漸變等泽论,盡量顯示“大小剛好合適的圖片資源”

8.避免同步的從網(wǎng)絡(luò)艾少、文件獲取數(shù)據(jù),Cell內(nèi)實(shí)現(xiàn)的內(nèi)容來自web佩厚,使用異步加載,緩存請(qǐng)求結(jié)果

9.渲染

9.1>減少subviews的個(gè)數(shù)和層級(jí)

子控件的層級(jí)越深说订,渲染到屏幕上所需要的計(jì)算量就越大抄瓦;如多用drawRect繪制元素潮瓶,替代用view顯示

9.2>少用subviews的透明圖層

對(duì)于不透明的View,設(shè)置opaque為YES钙姊,這樣在繪制該View時(shí)毯辅,就不需要考慮被View覆蓋的其他內(nèi)容(盡量設(shè)置Cell的view為opaque,避免GPU對(duì)Cell下面的內(nèi)容也進(jìn)行繪制)

9.3>避免CALayer特效(shadowPath)

給Cell中View加陰影會(huì)引起性能問題煞额,如下面代碼會(huì)導(dǎo)致滾動(dòng)時(shí)有明顯的卡頓:

view.layer.shadowColor?=?color.CGColor;

view.layer.shadowOffset?=?offset;

view.layer.shadowOpacity?=?1;

view.layer.shadowRadius?=?radius;?


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末思恐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子膊毁,更是在濱河造成了極大的恐慌胀莹,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件婚温,死亡現(xiàn)場離奇詭異描焰,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)栅螟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門荆秦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人力图,你說我怎么就攤上這事步绸。” “怎么了吃媒?”我有些...
    開封第一講書人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵瓤介,是天一觀的道長。 經(jīng)常有香客問我晓折,道長惑朦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任漓概,我火速辦了婚禮漾月,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胃珍。我一直安慰自己梁肿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開白布觅彰。 她就那樣靜靜地躺著吩蔑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪填抬。 梳的紋絲不亂的頭發(fā)上烛芬,一...
    開封第一講書人閱讀 49,985評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼赘娄。 笑死仆潮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的遣臼。 我是一名探鬼主播性置,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼揍堰!你這毒婦竟也來了鹏浅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤屏歹,失蹤者是張志新(化名)和其女友劉穎隐砸,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體西采,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凰萨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了械馆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胖眷。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖霹崎,靈堂內(nèi)的尸體忽然破棺而出珊搀,到底是詐尸還是另有隱情,我是刑警寧澤尾菇,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布境析,位于F島的核電站,受9級(jí)特大地震影響派诬,放射性物質(zhì)發(fā)生泄漏劳淆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一默赂、第九天 我趴在偏房一處隱蔽的房頂上張望沛鸵。 院中可真熱鬧,春花似錦缆八、人聲如沸曲掰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽栏妖。三九已至,卻和暖如春奖恰,著一層夾襖步出監(jiān)牢的瞬間吊趾,已是汗流浹背宛裕。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留论泛,地道東北人续滋。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像孵奶,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蜡峰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

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