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];
}
}