美文网首页
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