美文网首页
UITableView优化技巧

UITableView优化技巧

作者: MrLuckyluke | 来源:发表于2015-12-11 00:23 被阅读131次

UITableView最核心的思想就是UITableViewCell的重用机制。

UITableView的布局

UITableView最主要的两个回调方法是tableView:cellForRowAtIndexPath:和tableView:heightForRowAtIndexPath:。理想上我们是会认为UITableView会先调用前者,再调用后者,因为这和我们创建控件的思路是一样的,先创建它,再设置它的布局。但实际上却并非如此,我们都知道,UITableView是继承自UIScrollView的,需要先确定它的contentSize及每个Cell的位置,然后才会把重用的Cell放置到对应的位置。所以事实上,UITableView的回调顺序是先多次调用tableView:heightForRowAtIndexPath:以确定contentSize及Cell的位置,然后才会调用tableView:cellForRowAtIndexPath:,从而来显示在当前屏幕的Cell。

优化思路:

举个例子来说:如果现在要显示100个Cell,当前屏幕显示5个。那么刷新(reload)UITableView时,UITableView会先调用100次tableView:heightForRowAtIndexPath:方法,然后调用5次tableView:cellForRowAtIndexPath:方法;滚动屏幕时,每当Cell滚入屏幕,都会调用一次tableView:heightForRowAtIndexPath:、tableView:cellForRowAtIndexPath:方法。

重写drawRect方法就不需要用GCD异步线程了,因为drawRect本来就是异步绘制的。

//按需加载 - 如果目标行与当前行相差超过指定行数,只在目标滚动范围的前后指定3行加载。

```objc

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollViewwithVelocity:(CGPoint)velocitytargetContentOffset:(inout CGPoint *)targetContentOffset{

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

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

NSInteger skipCount =8;

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

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

NSMutableArray *arr = [NSMutableArrayarrayWithArray:temp];

if(velocity.y<0) {

NSIndexPath *indexPath = [temp lastObject];

if(indexPath.row+3

[arraddObject:[NSIndexPathindexPathForRow:indexPath.row+1inSection:0]];

[arraddObject:[NSIndexPathindexPathForRow:indexPath.row+2inSection:0]];

[arraddObject:[NSIndexPathindexPathForRow:indexPath.row+3inSection:0]];

}

}else{

NSIndexPath *indexPath = [temp firstObject];

if(indexPath.row>3) {

[arraddObject:[NSIndexPathindexPathForRow:indexPath.row-3inSection:0]];

[arraddObject:[NSIndexPathindexPathForRow:indexPath.row-2inSection:0]];

[arraddObject:[NSIndexPathindexPathForRow:indexPath.row-1inSection:0]];

}

}

[needLoadArraddObjectsFromArray:arr];

}

}

```

记得在tableView:cellForRowAtIndexPath:方法中加入判断:

```objc

if(needLoadArr.count>0&&[needLoadArr indexOfObject:indexPath]==NSNotFound) {

[cellclear];

return;

}

```

滚动很快时,只加载目标范围内的Cell,这样按需加载,极大的提高流畅度。

提前计算并缓存好高度(布局),因为heightForRowAtIndexPath:是调用最频繁的方法;

异步绘制,遇到复杂界面,遇到性能瓶颈时,可能就是突破口;

滑动时按需加载,这个在大量图片展示,网络加载的时候很管用!(SDWebImage已经实现异步加载,配合这条性能杠杠的)。

除了上面最主要的三个方面外,还有很多几乎大伙都很熟知的优化点:

正确使用reuseIdentifier来重用Cells

尽量使所有的viewopaque,包括Cell自身

尽量少用或不用透明图层

如果Cell内现实的内容来自web,使用异步加载,缓存请求结果

减少subviews的数量

在heightForRowAtIndexPath:中尽量不使用cellForRowAtIndexPath:,如果你需要用到它,只用一次然后缓存结果

尽量少用addView给Cell动态添加View,可以初始化时就添加,然后通过hide来控制是否显示

相关文章

网友评论

      本文标题:UITableView优化技巧

      本文链接:https://www.haomeiwen.com/subject/khxkhttx.html