下面根據(jù)這些優(yōu)化策略來使用代碼展示

1: 盡量少的Cell的類型
當Cell的結構基本差不多時候,可以將Cell只創(chuàng)建一種Cell,這樣Cell的體積會增大,但是Cell的數(shù)量不會有很多,
UITableViewCell的復用機制是離屏就會進入緩存池中,那么一屏可以有N個Cell,那個一種Cell的緩存數(shù)就是N+1,如果有M種Cell,那么緩存數(shù)就是M*N個.利用同一種類型的cell,去靈活利用view的hidden屬性,可以很好的降低Cell的類型數(shù)量,不過依照實際需求看.
typedefenum: NSUInteger {
FriendsterCellTypeNone = -1,//錯誤碼 不存在
FriendsterCellTypeAll =0,//default
FriendsterCellTypeImage,
FriendsterCellContent,} FriendsterCellType;
@interfaceFriendsterTableViewCell:UITableViewCell
@property(nonatomic,strong)FriendsterModel *model;//不設置照片 這個先可以不看,后面優(yōu)化會用到
@property(nonatomic,strong)FriendsterModel *noImageModel;
@end
2: 提前計算Cell的高度
系統(tǒng)會先調(diào)用“tableView:heightForRowAtIndexPath:”獲取每個Cell即將顯示的高度,從而確定整個UITableView的布局。然后才調(diào)用“tableView:cellForRowAtIndexPath”獲取每個Cell,我們也是在這里填充、設置Cell的。
在Model中計算并保存Cell的高度
@interfaceFriendsterModel:NSObject
@property(nonatomic,strong)NSString*icon_url;
@property(nonatomic,assign)CGRecticonF;
@property(nonatomic,strong)UIImage*iconImage;
@property(nonatomic,strong)NSString*content;
@property(nonatomic,assign)CGRectcontentF;
@property(nonatomic,strong)NSString*name;
@property(nonatomic,assign)CGRectnameF;
@property(nonatomic,strong)NSString*img_url;
@property(nonatomic,assign)CGRectimgF;
@property(nonatomic,assign)CGFloatcellHeight;
@property(nonatomic,assign)FriendsterCellType cellType;
@property(nonatomic,assign)BOOLisAnimation;
+ (instancetype)friendsterWithDict:(NSDictionary*)dict;
- (instancetype)initWithDict:(NSDictionary*)dict;
//這個方法是返回對應Cell的高度的,可以在數(shù)據(jù)層計算好每一個Cell的高度,之后直接從緩存中取出來就可以了,因為UITableView的調(diào)用之前會先把所有的Cell的高度全部獲取一遍,這里就是返回高度的地方,如果在這里大量計算,會延遲TableView的加載
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath{
FriendsterModel *model =self.dataArray[indexPath.row];
return model.cellHeight;
}
3: 緩存展示數(shù)據(jù)
例子: 內(nèi)容頁有類似于富文本形式的展示類的東西,
可以將富文本在數(shù)據(jù)層處理好,緩存在數(shù)據(jù)中,展示的時候直接復制即可,不用在創(chuàng)建NSMutableAttributedString 來組裝數(shù)據(jù)
4: 緩存展示Cell
對于一些簡單的,小的View,可以緩存在數(shù)據(jù)層,用的時候直接拿出來,不用在Cell里面進行重復創(chuàng)建.
5: 對于不透明的View,設置opaque為YES,這樣在繪制該View時,就不需要考慮被View覆蓋的其他內(nèi)容(盡量設置Cell的view為opaque,避免GPU對Cell下面的內(nèi)容也進行繪制).
6: 盡量減少 Cell 的視圖層級,可以使用異步繪制的方式,并且少用或不用透明的視圖。盡量顯示“大小剛好合適的圖片資源”
7: 避免離屏渲染,比如同時使用
view.layer.masksToBounds= YES;
view.layer.cornerRadius=20.0;
可以用 使用CAShapeLayer和UIBezierPath設置圓角.
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100,100,100,100)];
imageView.image= [UIImage imageNamed:@"3"];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.boundsbyRoundingCorners:UIRectCornerAllCorners cornerRadii:imageView.bounds.size];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];//設置大小
maskLayer.frame= imageView.bounds;//設置圖形樣子
maskLayer.path= maskPath.CGPath;
imageView.layer.mask= maskLayer;
[self.viewaddSubview:imageView];
8: 快速滑動時按需加載
快滑動過程中,只加載目標范圍內(nèi)的Cell,這樣按需加載,極大的提高流暢度。
- (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:[NSIndexPathindexPathForRow: indexPath.row-3 inSection: 0]];
[arr addObject:[NSIndexPathindexPathForRow: indexPath.row-2 inSection: 0]];
[arr addObject:[NSIndexPathindexPathForRow: indexPath.row-1 inSection: 0]];
}
}
[needLoadArr addObjectsFromArray:arr];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
...
if(needLoadArr.count>0 && [needLoadArr indexOfObject:indexPath] == NSNotFound) {
[cell clear];
return;
}
...
}
9: 圖片加載優(yōu)化:
當用戶手動 drag table view 的時候,會加載 cell 中的圖片; * 在用戶快速滑動的減速過程中,不加載過程中 cell
中的圖片(但文字信息還是會被加載,只是減少減速過程中的網(wǎng)絡開銷和圖片加載的開銷);
在減速結束后,加載所有可見 cell 的圖片(如果需要的話);
/*
優(yōu)化達到的效果
1: 當用戶手動 drag table view 的時候,會加載 cell 中的圖片;
2: 在用戶快速滑動的減速過程中,不加載過程中 cell 中的圖片(但文字信息還是會被加載,只是減少減速過程中的網(wǎng)絡開銷和圖片加載的開銷);
3: 在減速結束后,加載所有可見 cell 的圖片(如果需要的話);
4: 在減速結束后,需要顯示的Cell的圖片要優(yōu)先下載.
scrollViewWillBeginDragging 即將開始拖拽
scrollViewWillEndDragging: withVelocity: targetContentOffset: 即將停止拖拽
scrollViewDidEndDecelerating 已經(jīng)停止減速
進一步優(yōu)化
1: 如果內(nèi)存中有圖片的緩存,減速過程中也會加載該圖片
2: 如果圖片屬于 targetContentOffset 能看到的 cell,正常加載,這樣一來,快速滾動的最后一屏出來的的過程中,用戶就能看到目標區(qū)域的圖片逐漸加載
*/
//即將開始拖動
- (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView{
NSLog(@"%s",__func__);//
_isNeedLoadImage = NO;
}
//即將停止拖動 滾動很快時,只加載目標范圍內(nèi)的Cell,這樣按需加載,極大的提高流暢度。
- (void)scrollViewWillEndDragging:(UIScrollView*)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint*)targetContentOffset{
NSLog(@"%s",__func__);
// 先獲取當前開始減速時第幾行
NSIndexPath*ip = [self.tableView indexPathForRowAtPoint:CGPointMake(0, targetContentOffset->y)];
NSIndexPath*cip = [[self.tableView indexPathsForVisibleRows] firstObject];
NSLog(@"%@",ip);
NSLog(@"%@",cip);
NSIntegerskipCount =6;//判斷快速滑動的cell跨越的數(shù)量
if(labs(cip.row-ip.row)>skipCount) {
_isQuickScroll =YES;
}else{
_isQuickScroll =NO;
}
}
//即將開始減速- (void)scrollViewWillBeginDecelerating:(UIScrollView*)scrollView{
NSLog(@"%s",__func__);
_isDecelerationing =YES;
}
//已經(jīng)停止減速
- (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView{
NSLog(@"%s",__func__);
_isNeedLoadImage =YES;
_isDecelerationing =NO;
_isQuickScroll =NO;
//刷新當前屏幕可見CEll
[self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];
}
完成!!!!