UITableView优化的那些事儿
作为iOS开发,UITableView可能是平时我们打交道最多的UI控件之一,其重要性不言而喻。关于TableView,我想最核心的就是UITableViewCell的重用机制了。简单来说呢就是当TableView滚动时,会调tableView:cellForRowAtIndexPath:这个方法,TableView只会创建屏幕内或者只比屏幕多一点点的cell,当滚动需要展现新的cell的时候,TableView首先会把已经移出屏幕外的cell放入到缓存池中去,然后再从缓存池中取出新的cell用来展示,当缓存池中没有的时候,则会创建新的cell。但是cell可能不仅仅是一种,我们怎么来辨别我们需要的cell呢?苹果公司已经为我们做好了一切,我们只需要简单地设置一个identifier即可,TableView便可自动根据identifier从缓存池中去出相应cell出来复用。这样就极大的节省了内存的开销。 知道cell的复用原理后,我们再来看看TableView的回调方法。我们知道,TableView继承自UIScrollView,必须先确定它的contentSize和每个cell的位置,这样才能正确的放置每个cell。所以在创建或者复用cell之前,tableView会调用tableView:heightForRowAtIndexPath:来确定contentSize和每个cell的高度,之后再调用tableView:cellForRowAtIndexPath:显示相应的cell。然而此举对于那些成百上千不定高的cell,计算高度会相当消耗性能。所以首先我们围绕cell来看看TableView如何进行优化。1.cell复用这个很简单,只要注册一下,便会自动复用复制代码-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{static NSString *Identifier = @"cell";UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];if (!cell) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];}return cell;}
复制代码
这里说一句,有很多人会在这里给cell进行赋值操作,绑定数据,但是最近看了一篇文章https://medium.com/ios-os-x-development/perfect-smooth-scrolling-in-uitableviews-fd609d5275a5#.373u9fh4p,里面说到不要在这个方法中进行数据绑定,因为TableView会为每个cell调用一次这个方法,它应该快速执行,我们应该快速的返回cell重用实例。我们可以在tableView:willDisplayCell:forRowAtIndexPath:这个方法中进行数据绑定。2.cell的高度计算这边我们分为两种cell,一种是定高的cell,另外一种是动态高度的cella.定高的cell,应该采用如下方式:self.tableView.rowHeight = 88;
这个方法指定了所有cell高度都是88的tableview,rowHeight默认的值是44,所以一个空的TableView会显示成这个样子。对于定高cell,直接采用上面方式给定高度,不需要实现tableView:heightForRowAtIndexPath:以节省不必要的计算和开销。b.动态高度的cell我们需要实现它的代理,来给出高度:- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {// return xxx
}
这个方法给出后,上面的rowHeight的设置将会变成无效。在这个方法中,我们需要提高cell高度的计算效率,来节省时间。需要说明的是自从iOS8之后有了self-sizing cell的概念,cell可以自己算出高度,但目前市面上的公司最低支持iOS8,能用上这个方法可能还有好久。除了提高cell高度的计算效率之外,对于已经计算出的高度,我们需要进行缓存,对于已经计算过的高度,没有必要进行计算第二次。此外,具体对于如何优化cell高度计算,何时缓存cell高度,这篇博客给出了非常好的说明,强烈推荐有兴趣的深读一下。http://blog.sunnyxx.com/2015/05/17/cell-height-calculation/3.渲染 为了保证TableView的流畅,当快速滑动的时候,cell必须被快速的渲染出来。所以cell渲染的速度必须快。如何提高cell的渲染速度呢?a.当有图像时,预渲染图像,在bitmap context先将其画一遍,导出成UIImage对象,然后再绘制到屏幕,这会大大提高渲染速度。具体做法可以参考:《利用预渲染加速显示iOS图像》b.渲染最好时的操作之一就是混合(blending)了,所以我们不要使用透明背景,将cell的opaque值设为Yes,背景色不要使用clearColor,尽量不要使用阴影渐变等c.由于混合操作是使用GPU来执行,我们可以用CPU来渲染,这样混合操作就不再执行。可以在UIView的drawRect方法中自定义绘制,具体可参考:http://southpeak.github.io/blog/2015/12/20/perfect-smooth-scrolling-in-uitableviews/4.减少视图的数目我们在cell上添加系统控件的时候,实际上系统都会调用底层的接口进行绘制,大量添加控件时,会消耗很大的资源并且也会影响渲染的性能。当使用默认的UITableViewCell并且在它的ContentView上面添加控件时会相当消耗性能。所以目前最佳的方法还是继承UITableViewCell,并重写drawRect方法。5.减少多余的绘制工作在实现drawRect方法的时候,它的参数rect就是我们需要绘制的区域,在rect范围之外的区域我们不需要进行绘制,否则会消耗相当大的资源6.不要给cell动态添加subView在初始化cell的时候就添加好,然后根据需要来设置hide属性显示和隐藏7.异步化UI,不要阻塞主线程我们时常会看到这样一个现象,就是加载时整个页面卡住不动,怎么点都没用,仿佛死机了一般。原因是主线程被阻塞了。所以对于网路数据的请求或者图片的加载,我们可以开启多线程,异步话操作8.滑动时按需加载对应的内容复制代码
//按需加载 - 如果目标行与当前行相差超过指定行数,只在目标滚动范围的前后指定3行加载。
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{NSIndexPath *ip = [self indexPathForRowAtPoint:CGPointMake(0, targetContentOffset->y)];NSIndexPath *cip = [[self indexPathsForVisibleRows] firstObject];NSInteger skipCount = 8;if (labs(cip.row-ip.row)>skipCount) {NSArray *temp = [self indexPathsForRowsInRect:CGRectMake(0, targetContentOffset->y, self.width, self.height)];NSMutableArray *arr = [NSMutableArray arrayWithArray:temp];if (velocity.y<0) {            NSIndexPath *indexPath = [temp lastObject];           if (indexPath.row+33) {
[arr addObject:[NSIndexPath indexPathForRow:indexPath.row-3 inSection:0]];
[arr addObject:[NSIndexPath indexPathForRow:indexPath.row-2 inSection:0]];                 [arr addObject:[NSIndexPath indexPathForRow:indexPath.row-1 inSection:0]];             }         }         [needLoadArr addObjectsFromArray:arr];     } }
复制代码
记得在tableView:cellForRowAtIndexPath:方法中加入判断:if (needLoadArr.count>0&&[needLoadArr indexOfObject:indexPath]==NSNotFound) {[cell clear];return;
}
滑动很快时,只加载目标范围内的cell,这样按需加载(配合SDWebImage),极大提高流畅度。最后,对于TableView的优化还有很多方面没有提及,希望大家多多交流~参考文章https://medium.com/ios-os-x-development/perfect-smooth-scrolling-in-uitableviews-fd609d5275a5#.373u9fh4phttp://blog.sunnyxx.com/2015/05/17/cell-height-calculation/ http://southpeak.github.io/blog/2015/12/20/perfect-smooth-scrolling-in-uitableviews/

UITableView优化相关推荐

  1. UITableView 优化

    前言 UITableView 是我们开发中常用到的控件.其优化也是老生常谈的话题.笔者在这里抛砖引玉. 圆角问题 IM模块的头像, 笔者的项目用UIButton. 早就听说iOS 设置圆角会造成性能上 ...

  2. UITableView优化之按需加载

    滑动UITableView时,按需加载对应的内容 直接上代码: //按需加载 - 如果目标行与当前行相差超过指定行数,只在目标滚动范围的前后指定3行加载. - (void)scrollViewWill ...

  3. (0074)iOS开发之UITableView的优化

    写的很好引用 https://www.jianshu.com/p/af6b095aaaf3 前言 这篇文章对 UITableView 的优化主要从以下3个方面分析: 基础的优化准则(高度缓存, cel ...

  4. UITableView的优化技巧

    这段时间也看了很多关于tableview优化的文章,加上前段时间自己也做了一个同时仿微博和支付宝的项目,思考了一些关于UITableView的优化技巧.UITableView是iOS开发中最常用的控件 ...

  5. 刷新UITableView

    [from]http://www.superqq.com/blog/2015/08/18/ios-development-refresh-uitableview/ UITableView对于iOS开发 ...

  6. swif之UITableViewCell和UITableView常见属性复习

    1.UITableViewCell常见的属性: imageView 单元格图片 textLabel 图片右边的标签 detailTextLabel     右边标签下的小标签 accessoryTyp ...

  7. 一个iOS程序员的BAT面试经验

    转载于:http://www.techug.com/ios-bat-interview 随着各大公司春招的开始,很多小伙伴都行动起来了,我有幸能够加入百度并和大家分享自己的经验心得.由于我面试的都是比 ...

  8. iOS每日总结博客版:iOS开发历程中了解和学习的文章

    2019独角兽企业重金招聘Python工程师标准>>> #iOS开发进阶指导:入门->进阶->大神 top:入门无忧网,各语言ide入门 http://www.rm5u. ...

  9. 800000000000

    8000000000题@TOC 不属于使用SDWebImage步骤的是 A:下载SDWebImage的最新SDK​ B:把SDK导入工程中BackgroundColor​ C:关闭arc​ D:如果需 ...

最新文章

  1. 2010年8月blog汇总:敏捷个人和OpenExpressApp之建模支持
  2. IOS中UITableViewCell的重用机制原理
  3. leetcode 64. 最小路径和(递归 / 动态规划解法图解)(Java版)
  4. 噢,老天爷! 属于Java的协程终于来了!
  5. 【Spark】一条 SQL 在 Apache Spark 之旅(上)
  6. m3u8格式转换mp4软件_怎么把mkv格式转换成mp4?教你转换mkv格式的方法
  7. 免费 | 开源操作系统年度盛会最新日程曝光,邀您一同开启烧脑模式!
  8. @程序员,如何在五分钟内构建个人网盘服务?| 技术头条
  9. 目标检测-20种常用深度学习算法论文、复现代码汇总
  10. python--List extend()方法
  11. 从零实现深度学习框架——自动求导神器计算图
  12. Python实现Hart协议
  13. QQ聊天记录的相关代码
  14. 广州高清卫星地图 用百度卫星地图server下载 含标签、道路数据叠加 可商用
  15. 学习如何使用html和css样式将两张图片叠加到另一张图片上,实现微信扫一扫二维码效果
  16. 辉太郎看前端(js异步宏任务和微任务)
  17. spoon无法初始化至少一个步骤_通俗易懂:8大步骤图解注意力机制
  18. NEO4J-链路预测算法03-优先链接算法(Preferential Attachment)应用场景简介
  19. 基于DEM的坡度坡向分析
  20. ABP WEBAPI 跨域问题

热门文章

  1. Spring Boot使用maven打包成jar后将依赖jar一起打进jar文件
  2. photoshop8.0 安装步骤及注意事项
  3. mysql主从库配置方法
  4. android RefBase、sp、wp
  5. MySQL常用维护管理工具
  6. insmod 和modprobe的区别
  7. Ruby --- gem(RubyGems)安装与使用
  8. PyCharm 快捷操作
  9. oracle语句mysql数据库名称_查询oracle数据库中当前数据库所有表的名称
  10. Nginx学习之HTTP/2.0配置