UITableView性能优化篇

1、cell复用

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TXTestCell *cell = (TXTestCell *)[tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];

    return cell;
}

2、延迟数据绑定

cellForRowAtIndexPath:cell还没有被展示出来
willDisplayCell:在cell实例生成之后调用,可以在这里进行数据绑定

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    
}

3、cell高度给定方式

1、定高,直接给定cell的高度,不需要实现代理,系统默认44pt

self.tableView.rowHeight = 100;

2、动态高度,需要实现代理给出高度,实现代理后rowHeight给出的高度将为无效高度。在这个方法中我们需要提高cell高度的计算效率。

self.tableView.estimatedRowHeight = 118.f;
self.tableView.rowHeight = UITableViewAutomaticDimension;

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return indexPath.row >0 ? 59.f : 63.f;
}

4、cell的渲染

1、当有图像时,预渲染图像,详情见《Improving Image Drawing Performance on iOS》
2、不要使用透明背景,将cell的opaque设置为YES,背景色不要使用clearColor,尽量不要使用阴影渐变等。
3、混合操作是GPU执行,我们可以用CPU渲染,这样混合操作就不会执行,可以在UIView的drawRect方法中自定义绘制。
4、减少subviews的个数和层级。子控件的层级越深,渲染到屏幕上所需要的计算量就越大;如多用drawRect绘制元素,替代用view显示。
5、少用subviews的透明图层。对于不透明的View,设置opaque为YES,这样在绘制该View时,就不需要考虑被View覆盖的其他内容(尽量设置Cell的view为opaque,避免GPU对Cell下面的内容也进行绘制)。
6、CALayer给Cell中View加阴影会引起性能问题,如下面代码会导致滚动时有明显的卡顿:

view.layer.shadowColor = color.CGColor; 
view.layer.shadowOffset = offset;
view.layer.shadowOpacity = 1;
view.layer.shadowRadius = radius;

7、我们在cell上添加系统控件的时候,实际上系统都会调用底层的接口进行绘制,大量添加控件时,会消耗很大的资源并且也会影响渲染的性能。当使用默认的UITableViewCell并且在它的ContentView上面添加控件时会相当消耗性能。所以目前最佳的方法还是继承UITableViewCell,并重写drawRect方法。
8、在实现drawRect方法的时候,它的参数rect就是我们需要绘制的区域,在rect范围之外的区域我们不需要进行绘制,否则会消耗相当大的资源。
9、异步优化UI,不要阻塞主线程。
10、cell上的数据源分页加载。

5、离屏渲染

引起离屏渲染

1、为图层设置遮罩(layer.mask);
2、将图层的layer.masksToBounds = YES
view.clipsToBounds = YES;
3、将图层layer.allowsGroupOpacity = YES和layer.opacity小于1.0;
4、为图层设置阴影(layer.shadow *);
5、为图层设置layer.shouldRasterize = YES;
6、具有layer.cornerRadius,layer.edgeAntialiasingMask,layer.allowsEdgeAntialiasing的图层;
7、文本(任何种类,包括UILabel,CATextLayer,Core Text等);
8、使用CGContext在drawRect :方法中绘制大部分情况下会导致离屏渲染,甚至仅仅是一个空的实现。

解决离屏渲染

使用贝塞尔曲线UIBezierPath和Core Graphics框架绘制圆角

UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
imageView.image = [UIImage imageNamed:@"myImg"];       
//开始对imageView进行画图        
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);        
//使用贝塞尔曲线画出一个圆形图       
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:imageView.frame.size.width] addClip];        
[imageView drawRect:imageView.bounds];       
imageView.image = UIGraphicsGetImageFromCurrentImageContext();        
//结束画图        
UIGraphicsEndImageContext();        
[self.view addSubview:imageView];

使用CAShapeLayer和UIBezierPath设置圆角

UIImageView *imageView = [[UIImageViewalloc]initWithFrame:CGRectMake(100,100,100,100)];
imageView.image=[UIImageimageNamed:@"myImg"];
UIBezierPath *maskPath = [UIBezierPathbezierPathWithRoundedRect:imageView.boundsbyRoundingCorners:UIRectCornerAllCornerscornerRadii:imageView.bounds.size];
CAShapeLayer *maskLayer = [[CAShapeLayeralloc]init];
//设置大小        
maskLayer.frame = imageView.bounds;
//设置图形样子        
maskLayer.path = maskPath.CGPath;
imageView.layer.mask = maskLayer;
[self.viewaddSubview:imageView];

用CAShapeLayer的内存消耗少,渲染速度快,建议使用

6、shadow优化

对于shadow,如果图层是个简单的几何图形或者圆角图形,我们可以通过设置shadowPath来优化性能,能大幅提高性能。示例如下:

imageView.layer.shadowColor = [UIColorgrayColor].CGColor;
imageView.layer.shadowOpacity = 1.0;
imageView.layer.shadowRadius = 2.0;
UIBezierPath *path = [UIBezierPathbezierPathWithRect:imageView.frame]
imageView.layer.shadowPath = path.CGPath;

7、其他的一些方法

1.当我们需要圆角效果时,可以使用一张中间透明图片蒙上去。
2.使用ShadowPath指定layer阴影效果路径。
3.使用异步进行layer渲染(Facebook开源的异步绘制框架AsyncDisplayKit)。
4.设置layer的opaque值为YES,减少复杂图层合成。
5.尽量使用不包含透明(alpha)通道的图片资源。

  1. 尽量设置layer的大小值为整形值。
    7.直接让美工把图片切成圆角进行显示,这是效率最高的一种方案。
    8.很多情况下用户上传图片进行显示,可以让服务端处理圆角。
    9.使用代码手动生成圆角Image设置到要显示的View上,利用UIBezierPath(CoreGraphics框架)画出来圆角图片

你可能感兴趣的:(UITableView性能优化篇)