UITableView滑动性能优化扩展

一点UITableView滑动性能优化扩展

影响UITableView的滑动,有哪些因素呢? 
关于这一点,人眼能识别的帧率是60左右,这也就是为何,电脑屏幕的最佳帧率是60Hz。 
屏幕一秒钟会刷新60次(屏幕在一秒钟会从新渲染60次),那么每次刷新界面之间的处理时间,就是1/60,也就是1/60秒。也就是说,全部会致使计算、渲染耗时的操做都会影响UITableView的流畅。下面举例说明:算法

1.在主线程中作耗时操做 
耗时操做,包括从网络下载、从网络加载、从本地数据库读取数据、从本地文件中读取大量数据、往本地文件中写入数据等。(这一点,相信你们都知道,要尽可能避免在主线程中执行,通常都是建立一个子线程来执行,而后再回到主线程)数据库

2.动态计算UITableViewCell的高度,时间太久 
在iOS7以前,每个Cell的高度,只会计算一次,后面再次滑到这个Cell这里,都会读取缓存的高度,也即高度计算的代理方法不会再执行。可是到了iOS8,不会再缓存Cell的高度了,也就是说每次滑到某个Cell,代理方法都会执行一次,从新计算这个Cell的高度(iOS 9之后没测试过)。 
因此,若是计算Cell高度的这个过程过于复杂,或者某个计算使用的算法耗时很长,可能会致使计算时间大于1/60,那么必然致使界面的卡顿,或不流畅。数组

关于这一点,我之前的作法是在Cell中定义一个public方法,用来计算Cell高度,而后计算完高度后,将高度存储在Cell对应的Model中(Model里定义一个属性来存高度),而后在渲染Cell时,咱们依然须要动态计算各个子视图的高度。(多是没用什么太过复杂的计算或算法,时间都很短滑动也顺畅)缓存

其实,更优的作法是:再定义一个ModelFrame对象,在子线程请求服务器接口返回后,转换为对象的同时,也把各个子视图的frame计算好,存在ModelFrame中,ModelFrame 和 Model 合并成一个Model存储到数组中。这样在为Cell各个子控件赋值时,仅仅是取值、赋值,在计算Cell高度时,也仅仅是加法运算。性能优化

3.界面中背景色透明的视图过多 
为何界面中背景色透明的视图过多会影响UITableView的流畅?服务器

不少文章中都提到,可使用模拟器—>Debug—>Color Blended Layers来检测透明背景色,把透明背景色改成与父视图背景色同样的颜色,这样来提升渲染速度。网络

简单说明一下,就是屏幕上显示的全部东西,都是经过一个个像素点呈现出来的。而每个像素点都是经过三原色(红、绿、蓝)组合呈现出不一样的颜色,最终才是咱们看到的手机屏幕上的内容。在 iPhone5 的液晶显示器上有1,136×640=727,040个像素,所以有2,181,120个颜色单元。在15寸视网膜屏的 MacBook Pro 上,这一数字达到15.5百万以上。全部的图形堆栈一块儿工做以确保每次正确的显示。当你滚动整个屏幕的时候,数以百万计的颜色单元必须以每秒60次的速度刷新,这是一个很大的工做量。性能

每个像素点的颜色计算是这样的: 
R = S + D * (1 - Sa) 
结果的颜色 是子视图这个像素点的颜色 + 父视图这个像素点的颜色 * (1 - 子视图的透明度) 
固然,若是有两个兄弟视图叠加,那么上面的中文解释可能并不贴切,只是为了更容易理解。测试

若是两个兄弟视图重合,计算的是重合区域的像素点: 
结果的颜色 是 上面的视图这个像素点的颜色 + 下面这个视图该像素点的颜色 * (1 - 上面视图的透明度)优化

只有当透明度为1时,上面的公式变为R = S,就简单的多了。不然的话,就很是复杂了。 
每个像素点是由三原色组成,例如父视图的颜色和透明度是(Pr,Pg,Pb,Pa),子视图的颜色颜色和透明度是(Sr,Sg,Sb,Sa),那么咱们计算这个重合区域某像素点的颜色,须要先分别计算出红、绿、蓝。 
Rr = Sr + Pr * (1 - Sa), 
Rg = Sg + Pg * (1 - Sa), 
Rb = Sb + Pb * (1 - Sa)。 
若是父视图的透明度,即Pa = 1,那么这个像素的颜色就是(Rr,Rg,Rb)。 
可是,若是父视图的透明Pa 不等 1,那么咱们须要将这个结果颜色当作一个总体做为子视图的颜色,再去与父视图组合计算颜色,如此递推。

 
因此设置不透明时,能够为GPU节省大量的工做,减小大量的消耗。
相关文章
相关标签/搜索