UITableView的優(yōu)化(面試必備)

1. a.將cell及它的子控件設(shè)置為不透明的宜狐。b.盡量少用或不用透明圖層工碾。c.減少子控件的數(shù)量。d.盡量少用addView給Cell動態(tài)添加View罢艾,可以初始化時就添加,然后通過hide來控制是否顯示尽纽。e如果Cell內(nèi)現(xiàn)實的內(nèi)容來自web,使用異步加載,緩存請求結(jié)果這個在我的《iOS多圖下載案例》系列文章中有具體講解原理咐蚯,這個采用sdwebimage這個第三方框架即可。這幾個都是通過輕量級cell來對tableview進行優(yōu)化弄贿。

設(shè)置透明的話春锋,處理器需要繪制渲染在cell下方的視圖或需要引用很多系統(tǒng)方面的東西,影響渲染速度差凹。所以盡量設(shè)置其為不透明期奔,提升渲染的速度∥D颍可以將table cell及其子視圖的opaque屬性設(shè)為YES(默認(rèn)值)呐萌。其中的特例包括背景色,它的alpha值應(yīng)該為1(例如不要使用clearColor)谊娇;圖像的alpha值也應(yīng)該為1肺孤,或者在畫圖時設(shè)為不透明。渲染最慢的操作之一就是混合(blending)了济欢。

當(dāng)我們向cell添加大量添加控件時赠堵,對資源的開銷也會很大。這時候如果我們要優(yōu)化的話法褥,可以在自定義的cell重寫drawrect方法顾腊,也可以寫個draw方法。這里是需要異步繪制挖胃,但如果在重寫drawRect方法就不需要用GCD異步線程了杂靶,因為drawRect本來就是異步繪制的梆惯。這我就不舉例子了,大家可以看看coretext吗垮。


2.正確使用reuseIdentifier來重用Cell垛吗。

UITableView只需要一屏幕的UITableViewCell對象即可。因此在cell不可見時烁登,可以將其緩存起來怯屉,而在需要時繼續(xù)使用它即可。而UITableView也提供了這種機制饵沧,只需要簡單地設(shè)置一個identifier即可锨络。

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

UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

if(cell==nil) {

cell= [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault ?reuseIdentifier:@"cell"];

}

return cell;

}

3.提前計算并緩存好高度(布局),因為heightForRowAtIndexPath:是調(diào)用最頻繁的方法狼牺。

先舉個小實例:

- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{

return10;

}

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

UITableViewCell*cell = [tableViewdequeueReusableCellWithIdentifier:@"cell"];

if(cell==nil) {

cell= [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:@"cell"];

}

returncell;

}

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

NSLog(@"%ld",(long)indexPath.row);

return100;

}

@end

當(dāng)前屏幕顯示4個cell羡儿,總共5個cell。這里高度簡單設(shè)為100是钥,如果你的應(yīng)用需要做不等高cell掠归,那么每次你都要重新計算高度,嚴(yán)重影響性能悄泥,我這里只是打印一下虏冻,給大家看看效果。

打印結(jié)果:


通過打印結(jié)果弹囚,雖然我們只有5個cell厨相,屏幕顯示4個cell,但是heightforrow這個方法竟然執(zhí)行了5*5+4遍鸥鹉,如果我要顯示cell個數(shù)更多的話蛮穿,將調(diào)用更多次這個方法。所以優(yōu)化tableview的一個思想就是把高度緩存起來宋舷,方便多次調(diào)用绪撵。所以我們寫個數(shù)組瓢姻,將計算完的高度寫入數(shù)組祝蝠,下次用的時候直接數(shù)組里取。

實際應(yīng)用:

懶加載一個可變數(shù)組來存放高度:

- (NSMutableArray*)array{

if(!_array) {

_array= [NSMutableArrayarray];

}

return_array;

}

聲明一個變量height來存放高度幻碱,然后將高度放進可變數(shù)組里绎狭,放完后,這個方法就會從數(shù)組里取高度這樣你就不用計算高度褥傍。

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

CGFloatheight;

if(_array.count>indexPath.row) {

height =[[self.arrayobjectAtIndex:indexPath.row]floatValue];

}else{

Stautes*s =self.ary[indexPath.row];

height = s.cellHeight;

[self.arrayaddObject:[NSNumbernumberWithFloat:height]];

}

NSLog(@"%f---%lu",height,(unsignedlong)self.array.count);

returnheight;

}

我是在另一個類計算高度儡嘶,主要是根據(jù)后臺傳的視頻文字來進行判斷然后設(shè)置高度:

#import"Stautes.h"

@implementationStautes

- (CGFloat)cellHeight

{

if(_cellHeight==0) {

CGFloatspace =10;

/**圖像*/

CGFloaticonX = space;

CGFloaticonY = space;

CGFloaticonWH =30;

self.iconFrame=CGRectMake(iconX, iconY, iconWH, iconWH);

/**昵稱*/

CGFloatnameX =CGRectGetMaxX(self.iconFrame) + space;

CGFloatnameY = iconY;

NSDictionary*nameAtt =@{NSFontAttributeName: [UIFontsystemFontOfSize:17]};

//計算昵稱文字的尺寸

CGSizenameSize = [self.namesizeWithAttributes:nameAtt];

CGFloatnameW = nameSize.width;

CGFloatnameH = nameSize.height;

self.nameFrame=CGRectMake(nameX, nameY, nameW, nameH);

/** vip */

if(self.isVip) {

CGFloatvipX =CGRectGetMaxX(self.nameFrame) + space;

CGFloatvipW =14;

CGFloatvipH = nameH;

CGFloatvipY = nameY;

self.vipFrame=CGRectMake(vipX, vipY, vipW, vipH);

}

/**正文*/

CGFloattextX = iconX;

CGFloattextY =CGRectGetMaxY(self.iconFrame) + space;

CGFloattextW = [UIScreenmainScreen].bounds.size.width-2* space;

NSDictionary*textAtt =@{NSFontAttributeName: [UIFontsystemFontOfSize:14]};

//最大寬度是textW,高度不限制

CGSizetextSize =CGSizeMake(textW,MAXFLOAT);

CGFloattextH = [self.textboundingRectWithSize:textSizeoptions:NSStringDrawingUsesLineFragmentOriginattributes:textAttcontext:nil].size.height;

self.textFrame=CGRectMake(textX, textY, textW, textH);

/**配圖*/

if(self.picture) {//有配圖

CGFloatpictureWH =100;

CGFloatpictureX = iconX;

CGFloatpictureY =CGRectGetMaxY(self.textFrame) + space;

self.pictureFrame=CGRectMake(pictureX, pictureY, pictureWH, pictureWH);

_cellHeight=CGRectGetMaxY(self.pictureFrame) + space;

}else{

_cellHeight=CGRectGetMaxY(self.textFrame) + space;

}

}

NSLog(@"計算");

return_cellHeight;

}

@end

打印結(jié)果如下:太長我就放一段,計算9次后就不再計算了恍风,優(yōu)化了tableview蹦狂。


4.滑動的UITableView時誓篱,按需加載對應(yīng)的內(nèi)容

//按需加載 - 如果目標(biāo)行與當(dāng)前行相差超過指定行數(shù),只在目標(biāo)滾動范圍的前后指定3行加載凯楔。

-?(void)scrollViewWillEndDragging:(UIScrollView?*)scrollView?withVelocity:(CGPoint)velocity?targetContentOffset:(inout?CGPoint?*)targetContentOffset{

NSIndexPath?*ip?=?[self?indexPathForRowAtPoint:CGPointMake(0,?targetContentOffset->y)];

NSIndexPath?*cip?=?[[self?indexPathsForVisibleRows]?firstObject];

NSInteger?skipCount?=?8;

if(labs(cip.row-ip.row)>skipCount)?{

NSArray?*temp?=?[self?indexPathsForRowsInRect:CGRectMake(0,?targetContentOffset->y,?self.width,?self.height)];

NSMutableArray?*arr?=?[NSMutableArray?arrayWithArray:temp];

if(velocity.y<0)?{

NSIndexPath?*indexPath?=?[temp?lastObject];

if(indexPath.row+33)?{

[arr?addObject:[NSIndexPath?indexPathForRow:indexPath.row-3?inSection:0]];

[arr?addObject:[NSIndexPath?indexPathForRow:indexPath.row-2?inSection:0]];

[arr?addObject:[NSIndexPath?indexPathForRow:indexPath.row-1?inSection:0]];

}

}

[needLoadArr?addObjectsFromArray:arr];

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末窜骄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子摆屯,更是在濱河造成了極大的恐慌邻遏,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,207評論 6 521
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件虐骑,死亡現(xiàn)場離奇詭異准验,居然都是意外死亡,警方通過查閱死者的電腦和手機廷没,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,455評論 3 400
  • 文/潘曉璐 我一進店門糊饱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人腕柜,你說我怎么就攤上這事济似。” “怎么了盏缤?”我有些...
    開封第一講書人閱讀 170,031評論 0 366
  • 文/不壞的土叔 我叫張陵砰蠢,是天一觀的道長。 經(jīng)常有香客問我唉铜,道長台舱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,334評論 1 300
  • 正文 為了忘掉前任潭流,我火速辦了婚禮竞惋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘灰嫉。我一直安慰自己拆宛,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,322評論 6 398
  • 文/花漫 我一把揭開白布讼撒。 她就那樣靜靜地躺著浑厚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪根盒。 梳的紋絲不亂的頭發(fā)上钳幅,一...
    開封第一講書人閱讀 52,895評論 1 314
  • 那天,我揣著相機與錄音炎滞,去河邊找鬼敢艰。 笑死,一個胖子當(dāng)著我的面吹牛册赛,可吹牛的內(nèi)容都是我干的钠导。 我是一名探鬼主播震嫉,決...
    沈念sama閱讀 41,300評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼牡属!你這毒婦竟也來了责掏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,264評論 0 277
  • 序言:老撾萬榮一對情侶失蹤湃望,失蹤者是張志新(化名)和其女友劉穎换衬,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體证芭,經(jīng)...
    沈念sama閱讀 46,784評論 1 321
  • 正文 獨居荒郊野嶺守林人離奇死亡瞳浦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,870評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了废士。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叫潦。...
    茶點故事閱讀 40,989評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖官硝,靈堂內(nèi)的尸體忽然破棺而出矗蕊,到底是詐尸還是另有隱情,我是刑警寧澤氢架,帶...
    沈念sama閱讀 36,649評論 5 351
  • 正文 年R本政府宣布傻咖,位于F島的核電站,受9級特大地震影響岖研,放射性物質(zhì)發(fā)生泄漏卿操。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,331評論 3 336
  • 文/蒙蒙 一孙援、第九天 我趴在偏房一處隱蔽的房頂上張望害淤。 院中可真熱鬧,春花似錦拓售、人聲如沸窥摄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,814評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崭放。三九已至,卻和暖如春值骇,著一層夾襖步出監(jiān)牢的瞬間莹菱,已是汗流浹背移国。 一陣腳步聲響...
    開封第一講書人閱讀 33,940評論 1 275
  • 我被黑心中介騙來泰國打工吱瘩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人迹缀。 一個月前我還...
    沈念sama閱讀 49,452評論 3 379
  • 正文 我出身青樓使碾,卻偏偏與公主長得像蜜徽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子票摇,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,995評論 2 361

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