美文网首页
关于tableView的优化技巧

关于tableView的优化技巧

作者: 路在脚下了 | 来源:发表于2017-08-18 15:44 被阅读99次

什么样的tableView是很优异的?

  1. 滚动时,确保cell刷新帧率应该在 50+/s !
  2. 展示cell时,不能出现跳帧现象,导致换面不流畅。
  3. 最关键的是在创建cell或者从缓存池取cell时,让系统花费最少的时间,即尽可能的减少显示cell的计算量.

1. 行高要缓存

举个简单的栗子:如果现在要显示100个Cell,当前屏幕显示5个。那么全局刷新UITableView时, UITableView会先调用100次tableView:heightForRowAtIndexPath:方法,然后调用5次 tableView:cellForRowAtIndexPath:方法;滚动屏幕时,每当Cell滚入屏幕,都会调用 一次tableView:heightForRowAtIndexPath:tableView:cellForRowAtIndexPath:方 法。所以说要提前计算并缓存好高度,因为heightForRowAtIndexPath:是调用最频繁的方法,如果是使用MVVM搭建框架,可以在viewModel中添加行高属性,提前计算好行高。
如果是固定高度的cell,可以直接采用tableView.rowHeight = 88;的方式,这样写,就需要实现tableView:heightForRowAtIndexPath:方法了;如果实现这个方法,设置rowHeight就会失效。

2.不要动态创建子视图

意思是:cell所有的子视图都预先在初始化方法中创建,如果根据实际情况不需要显示的可以设置 hidden.这样能尽可能的减少cell创建或从缓存池取时因为布局子控件所消耗的时间.

3. 渲染

为了保证TableView的流畅,当快速滑动的时候,cell必须被快速的渲染出来。所以cell渲染的速度必须快。如何提高cell的渲染速度呢?

(1)当有图像时,预渲染图像,在bitmap context先将其画一遍,导出成UIImage对象,然后再绘制到屏幕,这会大大提高渲染速度。具体内容可以自行查找“利用预渲染加速显示iOS图像”相关资料。

(2)渲染最好时的操作之一就是混合(blending)了,所以我们不要使用透明背景,将cell的opaque值设为Yes,背景色不要使用clearColor,尽量不要使用阴影渐变等

(3)由于混合操作是使用GPU来执行,我们可以用CPU来渲染,这样混合操作就不再执行。可以在UIView的drawRect方法中自定义绘制。

4.减少视图的数目

我们在cell上添加系统控件的时候,实际上系统都会调用底层的接口进行绘制,大量添加控件时,会消耗很大的资源并且也会影响渲染的性能。当使用默认的UITableViewCell并且在它的ContentView上面添加控件时会相当消耗性能。所以目前最佳的方法还是继承UITableViewCell,并重写drawRect方法。

5.减少多余的绘制操作

在实现drawRect方法的时候,它的参数rect就是我们需要绘制的区域,在rect范围之外的区域我们不需要进行绘制,否则会消耗相当大的资源。

6.异步化UI,不要阻塞主线程

我们时常会看到这样一个现象,就是加载时整个页面卡住不动,怎么点都没用,仿佛死机了一般。原因是主线程被阻塞了。所以对于网路数据的请求或者图片的加载,我们可以开启多线程,将耗时操作放到子线程中进行,异步化操作。这个或许每个iOS开发者都知道的知识,不必多讲。

7. 不要给cell动态添加subView

在初始化cell的时候就将所有需要展示的添加完毕,然后根据需要来设置hidden属性显示和隐藏。

8. 懒加载图片

快速滑动的时候,不要加载图片,滑动停止时,再加载图片。这样做可以防止在快速滑动时加载图片导致的卡顿问题。

9. 图片圆角优化

我们设置圆角一般通过如下方式:

imageView.layer.cornerRadius=CGFloat(10);
imageView.layer.masksToBounds=YES;

这样处理的渲染机制是,GPU在当前屏幕缓冲区外新开辟一个渲染缓冲区进行工作,也就是离屏渲染,这会给我们带来额外的性能损耗,如果这样的圆角操作达到一定数量,会触发缓冲区的频繁合并和上下文的的频繁切换,性能的代价会宏观地表现在用户体验上——掉帧。

优化方案1:使用贝塞尔曲线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];

优化方案2:使用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];

相关文章

网友评论

      本文标题:关于tableView的优化技巧

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