1. a.將cell及它的子控件設置為不透明的。b.盡量少用或不用透明圖層。c.減少子控件的數(shù)量。d.盡量少用addView給Cell動態(tài)添加View,可以初始化時就添加,然后通過hide來控制是否顯示。e如果Cell內(nèi)現(xiàn)實的內(nèi)容來自web,使用異步加載,緩存請求結果這個在我的《iOS多圖下載案例》系列文章中有具體講解原理,這個采用sdwebimage這個第三方框架即可。這幾個都是通過輕量級cell來對tableview進行優(yōu)化。
設置透明的話,處理器需要繪制渲染在cell下方的視圖或需要引用很多系統(tǒng)方面的東西,影響渲染速度。所以盡量設置其為不透明,提升渲染的速度??梢詫able cell及其子視圖的opaque屬性設為YES(默認值)。其中的特例包括背景色,它的alpha值應該為1(例如不要使用clearColor);圖像的alpha值也應該為1,或者在畫圖時設為不透明。渲染最慢的操作之一就是混合(blending)了。
當我們向cell添加大量添加控件時,對資源的開銷也會很大。這時候如果我們要優(yōu)化的話,可以在自定義的cell重寫drawrect方法,也可以寫個draw方法。這里是需要異步繪制,但如果在重寫drawRect方法就不需要用GCD異步線程了,因為drawRect本來就是異步繪制的。這我就不舉例子了,大家可以看看coretext。
2.正確使用reuseIdentifier來重用Cell。
UITableView只需要一屏幕的UITableViewCell對象即可。因此在cell不可見時,可以將其緩存起來,而在需要時繼續(xù)使用它即可。而UITableView也提供了這種機制,只需要簡單地設置一個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
當前屏幕顯示4個cell,總共5個cell。這里高度簡單設為100,如果你的應用需要做不等高cell,那么每次你都要重新計算高度,嚴重影響性能,我這里只是打印一下,給大家看看效果。
打印結果:

通過打印結果,雖然我們只有5個cell,屏幕顯示4個cell,但是heightforrow這個方法竟然執(zhí)行了5*5+4遍,如果我要顯示cell個數(shù)更多的話,將調(diào)用更多次這個方法。所以優(yōu)化tableview的一個思想就是把高度緩存起來,方便多次調(diào)用。所以我們寫個數(shù)組,將計算完的高度寫入數(shù)組,下次用的時候直接數(shù)組里取。
實際應用:
懶加載一個可變數(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ù)后臺傳的視頻文字來進行判斷然后設置高度:
#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
打印結果如下:太長我就放一段,計算9次后就不再計算了,優(yōu)化了tableview。

4.滑動的UITableView時,按需加載對應的內(nèi)容
//按需加載 - 如果目標行與當前行相差超過指定行數(shù),只在目標滾動范圍的前后指定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];
}
}