iOS UITableView性能优化

一、CPU 资源消耗原因和解决方案

1、对象创建,尽量使用轻量的对象代替重量的对象,例如用CALayer代替UIView
2、对象调整,尽量减少不必要的UI属性修改
3、对象销毁,可以异步放到后台线程去销毁
4、布局计算,尽量提前计算好布局,最好一次性调整好对应属性
5、Autolayout,在复杂布局时尽量少使用Autolayout
6、文本计算,参考UILabel内部的计算方式,在后台线程用[NSAttributedString boundingRectWithSize:options:context:] 来计算文本宽高,用 -[NSAttributedString drawWithRect:options:context:] 来绘制文本
7、文本渲染,可以自定义控件,用 TextKit 或最底层的 CoreText 对文本异步绘制
8、图片的解码,在后台线程先把图片绘制到 CGBitmapContext 中,然后从 Bitmap 直接创建图片
9、图像的绘制,图像的绘制通常是指用那些以 CG 开头的方法把图像绘制到画布中,然后从画布创建图片并显示这样一个过程,这个过程可以放到后台线程进行

二、GPU 资源消耗原因和解决方案

GPU 处理的事情:接收提交的纹理(Texture)和顶点描述(三角形),应用变换(transform)、混合并渲染,然后输出到屏幕上。
1、纹理的渲染
2、视图的混合,view的opaque属性设置成YES
3、图形的生成,把需要显示的图形在后台线程绘制为图片,避免使用圆角、阴影、遮罩等属性

1、预排版

从接口获取数据转成model之后,先在后头线程算好各个控件应该显示的frame及cell的高度,封装成CellLayout对象。在tableview执行代理方法时直接取出数据布局,甚至可以把CellLayout对象缓存进内存中,这样用户滚动tableview时可以最大程度的提高性能。

2、预渲染

cell内容的离屏渲染会造成较大的GPU消耗,当要使用到Layer 的 border、corner、shadow、mask 等方法时,可以在后台线程预渲染,然后单独缓存到图片缓存的队列中去

- (UIImage *)imageWithCornerRadius:(CGFloat)radius {
    CGRect rect = (CGRect){0.f, 0.f, self.size};
    UIGraphicsBeginImageContextWithOptions(self.size, NO, UIScreen.mainScreen.scale);
    CGContextAddPath(UIGraphicsGetCurrentContext(),
                     [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath);
    CGContextClip(UIGraphicsGetCurrentContext());
    [self drawInRect:rect];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}
3、异步绘制
4、全局并发控制
3、更高效的异步图片加载

UIImageView相对UIView来说会带来额外的性能消耗,如果对性能有严格的要求,可以使用UIView.layer.contents来代替UIImageView,为此可以为CALayer加上setImageWithURL:方法。

4、进一步优化性能

减少view上图层的数量,用CALayer代替UIView,
将cell按类型划分,减少不必要的视图对象和操作,

5、检测性能的工具

FPS 指示器 YYFPSLabel 可以监测当前页面的帧数。
MLeaksFinder 可以检测内存泄露

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