浅谈UITableView性能优化

UITableView作为iOS中最频繁使用的控件之一,其性能优化是必须要考虑的,下面和大家讨论讨论性能优化的方法。如有不足或错误,请大家指出,共同交流进步。

性能降低的原因####

  • cellForRowAtIndexPath方法中处理了过多业务
  • tableViewCell的subView层级复杂,做了大量透明处理
  • cell的高度动态变化时计算方式不对

优化方案####

针对cellForRowAtIndexPath方法中处理过多业务的优化方法####
1.如果cell显示的内容来自网络,那么确保这些内容是通过异步下载
2.在cellForRowAtIndexPath中尽量做更少的操作,最好是在别的地方
	算好,这个方法里只做数据的显示,如果需要做一些处理,那么最好做
	一次之后将结果储存起来
3.cell做数据绑定的时候,最好在willDisPlayCell里面进行,其他操作
	在cellForRowAtIndexPath,因为前者是第一页有多少条就执行多少次,
	后者是第一次加载有多少个cell就执行多少次,而且调用后者的时候cell
	还没显示
4.读取文件,写入文件,最好是放在子线程,或先读取好,让tableView去显示
针对视图过多和透明处理的优化方法#####
1.尽量将View设置为不透明,包括cell本身
2.减少subview的数量,不要去添加或移除view,要就显示,不要就隐藏。
针对cell高度计算的优化方法#####
1.如果cell的高度固定,通过:self.tableView.rowHeight = 99;方法比较好
2.如果cell的高度不固定,使用heightForRowAtIndexPath:方法
3.使用rowHeight,sectionFooterHeight和sectionHeaderHeight来设置
	一个恒定高度,而不是从代理中获取
4.FDTemplateLayoutCell的高度预缓存是一个优化功能,利用RunLoop空闲时间执行
	预缓存任务计算,当用户正在滑动列表时显然不应该执行计算任务影响滑动体验。

FDTemplateLayoutCell原理

  • 当用户正在滑动UIScrollView时,RunLoop将切换到UITrackingRunLoopMode接收滑动手势和处理滑动事件(包括减速和弹簧效果),此时,其他Mode(除NSRunLoopCommonModes这个组合Mode)下的事件将全部暂停执行,来保证滑动事件的优先处理,这也是iOS滑动顺畅的重要原因

  • 注册RunLoopObserver可以观测当前RunLoop的运行状态,并在状态机切换时收到通知:

    RunLoop开始

    RunLoop即将处理Timer

    RunLoop即将处理Source

    RunLoop即将进入休眠状态

    RunLoop即将从休眠状态被事件唤醒

    RunLoop退出

  • 分解成多个RunLoop Source任务,假设列表有20个cell,加载后展示了前5个,那么开启估算后,tableView只计算了这5个的高度,此时剩下15个就是预缓存的任务,而我们并不希望这15个计算任务在同一个RunLoop迭代中同步执行,这样会卡顿UI,所以应该把它们分别分解到15个RunLoop迭代中,这时就需要手动向RunLoop中添加Source任务(由应用发起和处理的是Source0 任务)

posted @ 2016-11-02 15:44  狼牙战士  阅读(467)  评论(0编辑  收藏  举报