UITableView几乎是最常用的控件之一,在开发中,经常需要对UITableView进行性能调优,提高用户体验
最基本的规则
- cell的复用
-
heightForRowAtIndexPath
在cellForRowAtIndexPath
之前调用,遵循UIScrollView中必须先计算contentSize-
cellForRowAtIndexPath
:仅仅当cell显示的时候才会调用 -
heightForRowAtIndexPath
:- 初始化的时候,如果有N行,那么会执行N次
- 调用reloadData方法,又会执行N次
- 显示的cell又会调用该方法
-
尽量少的cell种类
由于复用机制的存在,假设cell有M种,一个屏幕能容下的cell个数为N个,那么缓冲池中将会最多存在M x N个cell对象,而如果只有一种cell的话,最多只会有N个对象在缓存池中
定高的cell使用rowHeight
如果所有cell是统一高度的,那么避免使用代理方法去执行多次,直接设置rowHeight属性即可
提前计算并缓存cell的高度
在基本规则中可以看到,heightForRowAtIndexPath
方法会调用非常多的次数,如果将高度计算放在方法中,那么可想而知,CPU会存在大量的消耗。所以,对于cell高度的计算,应该在从网络获取到数据的时候就进行计算,并且把计算的结果缓存起来。具体的做法,可以在数据模型model对象中添加一个cell高度的属性,但是通常model类一般没有实现,就只有属性,所以最好的方式是添加到viewModel中。
提前创建并缓存真正需要显示的数据
有些从服务器中拿到的数据,并不能用于视图的显示,这些数据需要做一些处理才能用于视图显示。同样,我们可以在基本规则中看到,cellForRowAtIndexPath
也会执行多次,所以这些处理不应该直接放在该方法中。而应该在从网络获取到数据的时候就进行处理,同时缓存起来作为一个属性。通常这也是MVVM模式中VM所做的操作之一。
按需加载cell
在滑动的过程中,计算滚动目标范围内的cell进行加载,而不加载滑动过程中的cell,通过监听UIScrollView的代理方法来完成
避免使用透明图层
设置图层透明,系统会将透明图层和下面的视图进行混合,而这种操作属于渲染操作中很慢的操作
异步绘制
如果自定义cell的时候存在大量的子控件,那么这时候需要选择使用异步绘制,来防止创建多个子对象,耗费CPU资源。开启子线程直接绘制元素而非创建对象。除此之外还可以通过重写drawRect方法进行元素的绘制,drawRect方法本身是异步的。