iOS_项目优化(tableview的优化)

在项目开发中如果你没用到过Tableview,那请你去火星好吗。既然都用到了Tableview,那么如何优化就是个问题了。网上查了一些博客结合自己的一些经历,讲一下。

为什么会卡顿、掉帧、

先上图
渲染图.png

CPU:对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制
GPU:纹理的渲染
那这个卡顿掉帧是怎么发生的呢。
我们都知道iPhone的屏幕刷新是60,按照60FPS的刷帧率,每隔16ms就会有一次VSync信号。而产生卡顿掉帧就是因为CPU或者GPU所花费的时间过长,导致垂直信号来的时候,CPU计算或者GPU渲染未完成,从而掉帧。上一次的还没能传递过来信号,下一次的又开始了。所以,就造成了卡顿。
既然上面都说了事因为cpu和cpu花费的时间太长所引起的,那我们就从这两个方面入手解决。

1.CPU优化

1.固定高度的cell

self.tableView.rowHeight = 88;

2.动态高度的cell
现在对于动态高度这种情况,一般我们用系统的自动适配就可以满足。现在很少遇到还需要自己计算高度的情况。
不过还是要说在计算高度的时候,提前计算好cell的高度,缓存到数据源模型中。

 CGFloat contentW = [UIScreen mainScreen].bounds.size.width - 80;
    if (contentW != _lastContentWidth) {
        _lastContentWidth = contentW;
        CGRect textRect = [_remark boundingRectWithSize:CGSizeMake(contentW, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14]} context:nil];
        if (textRect.size.height > 20) {
            _shouldShowxiaButton = YES;
        } else {
            _shouldShowxiaButton = NO;
        }
    }

在model中把高度计算出来。

3 滑动过程中尽量减少重新布局
自动布局就是给控件添加约束,约束最终还是转换成frame。所以在满足业务需求情况下,如果图层层次较为复杂,要尽量减少自动布局约束,转为手动计算布局,大量的约束重叠也会增加cpu的计算量。

按需加载
// 按需加载 - 如果目标行与当前行相差超过指定行数,只在目标滚动范围的前后指定3行加载。
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    NSIndexPath *ip = [self.tableView indexPathForRowAtPoint:CGPointMake(0, targetContentOffset->y)];   // 停止拖拽后,预计滑动停止后到的偏移量
    NSIndexPath *cip = [[self.tableView indexPathsForVisibleRows] firstObject]; // 当前可视区域内 cell 组
    NSInteger skipCount = 8;
    NSLog(@"targetContentOffset = %f",targetContentOffset->y);
    NSLog(@"indexPathForRowAtPoint = %@",ip);
    NSLog(@"visibleRows = %@",[self.tableView indexPathsForVisibleRows]);
    if (labs(cip.row - ip.row) > skipCount) {   // labs-返回 x 的绝对值,进入该方法,说明滑动太厉害了,预计停留位置与当前可视区域范围内差 8 个cell 以上了.
        // 拖拽停止滑动停止后,即将显示的 cell 索引组
        NSArray *temp = [self.tableView indexPathsForRowsInRect:CGRectMake(0, targetContentOffset->y, self.tableView.width, self.tableView.height)];
        NSMutableArray *arrM = [NSMutableArray arrayWithArray:temp];
        NSLog(@"temp = %@",temp);
        if (velocity.y < 0) {   // 向上滑动-即加载更多数据
            NSIndexPath *indexPath = [temp lastObject];
            if (indexPath.row + 3 < self.dataSource.count) {    // 滑动停止后出现的 cell 索引仍在数据源范围之内
                [arrM addObject:[NSIndexPath indexPathForRow:indexPath.row + 1 inSection:0]];
                [arrM addObject:[NSIndexPath indexPathForRow:indexPath.row + 2 inSection:0]];
                [arrM addObject:[NSIndexPath indexPathForRow:indexPath.row + 3 inSection:0]];
            }
        } else {    // 向下滑动-加载之前的数据
            NSIndexPath *indexPath = [temp firstObject];
            if (indexPath.row > 3) {
                [arrM addObject:[NSIndexPath indexPathForRow:indexPath.row - 3 inSection:0]];
                [arrM addObject:[NSIndexPath indexPathForRow:indexPath.row - 2 inSection:0]];
                [arrM addObject:[NSIndexPath indexPathForRow:indexPath.row - 1 inSection:0]];
            }
        }
        
        [self.needLoadArray addObjectsFromArray:arrM];
    }
}

你可能感兴趣的:(iOS_项目优化(tableview的优化))