关于UITableView的性能优化,网络上也有一些总结。在这里就介绍下我们项目中遇到的问题以及对应的解决方法。相信我们遇到的问题也有一定的普适性,能够作为其他问题的优化方案。

Instruments

要对UITableView的性能进行优化,有一个工具肯定是不能少的,那就是Instruments,如果还不知道Instruments,建议先去看看相应的Apple Docoment。在开始着手优化你的UITableView的时候,不妨先用Instruments来看看你的UITableView看看你的代码的瓶颈究竟在哪里,不要轻易的对代码下判断,耗时不耗时。这里有个例子,当时我发现我们项目中有一个UITableView的滚动特别不顺畅,而这个UITableViewcell中的布局也确实很复杂,优化了一段时间后却发现滚动还是一样的不顺畅,打开Instruments工具Profile,立刻就发现了初始化Cell的代码占据了大量的运行时间,第一反应就是Reuse Identifier写错了。果不其然,查了一下xib和代码中的Identifier,哪位粗心程序猿同学没有两处的Identifier设为一致,导致每次都重新生成了一个Cell

其实这是个非常简单的问题,但凡使用过UITableView的人都知道要对Cell进行重用。但是这却是在优化中特别容易被忽略的点,这个例子是为了说明使用Instruments的重要性,它能给我们的优化带来很大的方便。

将属性设置代码放在正确的位置

再来谈谈另一个容易被忽略的点。也是对我们的项目Profile的时候发现的问题。这可能与每个人的编码习惯以及编程经验有关。在我们的项目代码中,我发现CustomCell方法中的某些属性设置操作在CustomCell方法中占了很大一部分时间,比如利用layer设置圆角、设置阴影、设置遮罩、设置图片等操作。仔细阅读代码后发现,其实这部分代码完全可以提前到awakeFromNib或者是init方法中去,但是直接写到了CustomCell方法中了,这就等于每次CellForRowAtIndexPath:时就会运行这些方法,其实也可以归结到重用的问题中去。

异步加载

既然讲到了CustomCell方法,就继续说几个可以在这里面优化的地方。iOS 6之后在很多控件中,Apple给我们提供了attributedText方法,以前需要使用Core Text才能完成的工作现在使用attributedText方法就能简单的完成了,给我们提供了很大的便利。但是在优化的时候,发现attributedText方法的耗时是非常大的,如果设置了图片作为attachment,那么就更加耗时了。因为闭源的原因,也不清楚究竟是什么原因引起的。既然这么耗时,又无法避免,那就只能直面他了,刚正面!优化用到的方法也很简单,就是异步的去执行这些操作。开个异步队列(非主队列)去构建这个attributedString,然后回到主队列里来设置attributedText,因为在iOS中UI操作必须要在主线程中进行嘛,不然会造成不可预知的后果,这个不可预知的后果据我观察一般就是UI不会立马更新。那么这里又有一个常用的优化方法了,其实不只针对UITableView,其他场合也能适用——把耗时的操作异步的去处理,然后回到主线程中更新UI。在我们的项目中,某些CustomCell方法因为业务需求,需要访问Disk。显然,IO操作是耗时大户,滑动的时候有明显的卡顿,也是采用了异步方式来处理的。

容易忽视的stringWithFormat:

在优化中,还发现了一个很隐蔽的问题。如果你的CustomCell方法中有大量的stringWithFormat:操作的话,你可能需要在字符串的优化上下点力气。因为不幸的是stringWithFormat:操作也会造成不可忽视的开销,听起来很奇怪吧。当时我在Profile的时候也惊呆了,为啥这个操作会造成性能瓶颈。幸好我们有解决方案。我们可以用C Style的方式来构造我们的字符串!事实证明这能减少不小开销,如果你的CustomCell方法中有大量的stringWithFormat:方法,那么性能提升的效果应该非常明显。下面这段代码可以用来进行CObjC字符串的转换:

char cString[255];    // 这里要根据实际情况开辟大小
sprintf(string, "Click: %d", numberOfClick);
NSString *objCString = [[NNString alloc] initWithUTF8String:cString];

GIF

因为业务需求,需要在某些Cell中添加GIF图片,Gif图片本来就比较吃资源,满屏的Cell每个都有一个GIF在动,想想就酸爽。一开始是使用FlAnimatedImage在每个Cell中添加一个GIF View,居然也没人发现有问题(应该是发现有问题,但是觉得问题不大),直到第一版本上架了也没人发现。某天我没事在优化的时候发现我的iPhone 5s已经烫的可以煎鸡蛋了,然后用Instruments一跑,不跑不知道,一跑吓一跳,停留在这个UITableView不操作的时候,FlAnimatedImage一直在创建线程,不烧CPU才怪呢。因为这个GIF还不算特别复杂,想了想可以自己画,然后用几个动画就能做出一样的效果,果断换了解决方案,换完之后简直顺畅。

不要忘记scrollViewDidScroll

我觉得这应该又是一个偷懒的结果。同样是在Instruments里发现的问题,scrollViewDidScroll:方法莫名其妙的占了很多运行时间。打开来一看,哦!原来是要记录每次用户滑动后停下的位置,显然放在scrollViewDidScroll:里是不合适的,因为随便滚动一下,scrollViewDidScroll:就调用了N次。果断转移代码,想了下丢到了scrollViewWillEndDragging:withVelocity:targetContentOffset:代理方法中去了,利用这个targetContentOffset就能解决啦。和CellForRowAtIndexPath:方法一样,这个方法调用的频率也很高,迫不得已不在在里面放耗时的代码。

图片!图片!

图片一直是吃资源的大户,网络图片的异步加载应该算是使用UITableViewCell的初级技术,所以这里讲的并不是图片的加载。圆角图片,相信都见过,四个角圆圆的那种矩形图片,看起来萌萌的。圆角的实现方式也有好多种:配合使用layercornerRadiusmaskToBounds来实现、使用Core Graphics绘制(用UIBezierPath添加Clip)、使用图片遮罩等等。如果只有一个圆角图片,那么可能不会造成大的影响,但是如果每个Cell中都有圆角图片,那么建议是采用图片遮罩的形式来实现,因为这种方法效率更高。

图片加载还有个小技巧就是当图片在异步加载的时候,图片所在的Cell滚动出了屏幕,那么立马把这个下载的操作给Cancel掉,避免不必要的资源消耗。

[UIImage imageNamed:] 的数据会缓存在内存中,而[UIImage imageWithContentOfFile:]的数据则不会。如果你需要在Cell中频繁的设置几个图片,那么在Cell中使用一个UIImage对象来保存住这些Image,也会对性能有所提升。

以上是我在项目中遇到的一些UITableView优化的问题。其实网上还有很多经验,这里摘抄一些作为记录,来源都在最后的Reference中有给出。

  • 减少Subview的个数和层级。使用一个UIViewoverride drawRect:方法来绘制所有内容能够提升UITableView的性能。主要是因为GPU负责来renderingcompositing,层级多了之后CPU需要做的合成工作变得复杂,所以可能还不如drawRect:使用CPU来绘制比较快,这其中的原因也很复杂,不是任何时候使用drawRect:都能提升性能的。 而且一般并不推荐这么做,这里有非常详细的解答。
  • Subviewopaque属性设置为YES(不透明了就告诉GPU不用再渲染此view下的图层了,GPUUITableView``scroll的时候做了大量的工作)
  • CALayerShouldRasterize设置为YESShouldRasterize告诉系统可以直接使用Cache的备份,如果View的内容不会改变,可以使用,否则会有副作用)
  • 不要拉伸Cell中的图片。
  • 如果是动态高度的Cell,可以想办法缓存Cell的高度,避免每次计算。
  • 使用Instruments找到当前的瓶颈是在CPU还是GPU上。链接
  • 如果Cell有阴影,尽量使用图片而不是操作layer来绘制。

除了以上技术上可以对UITableView的性能进行优化外,还可以从加载逻辑上对UITableView的性能进行优化。

这篇文章就从图片的加载逻辑上做了优化,达到提升性能的目的。 主要思想是:用户在滑动UITableView时,不加载快速滑动过程中的图片,预先加载UITableView滚动停下位置的图片。

UITableView性能优化的更多相关文章

  1. 【原/转】UITableview性能优化总结

    UITableView作为ios中使用最频繁的控件之一,其性能优化也是常常要面对的,尤其是当数据量偏大并且设备性能不足时.本文旨在总结tableview的几个性能优化tips,并且随着认识的深入,本文 ...

  2. UITableView性能优化及手工绘制UITableViewCell

    提高表视图的性能 UITableView作为应用中最常用的视图,它的性能优化问题几乎是经常提及.下面对在非网络访问情况下的表视图性能优化进行了主要的几点说明: 1.自定义类或XIB文件时 在系统提供的 ...

  3. UITableView性能优化【本文摘自智车芯官网】

    UITableView是个表格视图,可以在表格行空间中添加多个子控件,UITableView继承了UIScrollView,默认状态下可以堆单元格进行滚动,所有的UITableViewControll ...

  4. uitableview性能优化(转)

    这个感觉写的很好 收藏一下 以备后用 转自 http://www.cnblogs.com/pengyingh/articles/2354714.html 在iOS应用中,UITableView应该是使 ...

  5. iOS边练边学--UITableView性能优化之三种方式循环利用

    一.cell的循环利用方式1: /** * 什么时候调用:每当有一个cell进入视野范围内就会调用 */ - (UITableViewCell *)tableView:(UITableView *)t ...

  6. UITableView 性能优化

    网络图片异步加载,SDWebImage. 文字直接 drawInRect/drawAtPoint 绘制,参考 ABTableViewCell,AdvancedTableViewCells. 本地图片也 ...

  7. 【解决方法】UITableView 性能优化笔记

    1.网络图片异步载入,SDWebImage. 2.文字直接 drawInRect/drawAtPoint 绘制,參考 ABTableViewCell.AdvancedTableViewCells. 3 ...

  8. iOS回顾笔记(07) -- UITableView的使用和性能优化

    iOS回顾笔记(07) -- UITableView的使用和性能优化 如果问iOS中最重要的最常用的UI控件是什么,我觉得UITableView当之无愧!似乎所有常规APP都使用到了UITableVi ...

  9. iOS_UITableView性能优化那些事

    UITableView在实际开发中使用频率实在是很高, 因此, UITableView的性能优化是必不可少的, 本文下面就略微总结一下UITableView性能优化那些事. 本文着重介绍具体方法, 原 ...

随机推荐

  1. 【mysql的设计与优化专题(2)】数据中设计中的范式与反范式

    设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小.但是有些时候一昧的追求范式减少冗余,反而会降低数据读写 ...

  2. [Unity菜鸟] 笔记2 —— 问题篇

    记录在学习<Unity 3.x 游戏开发 经典教材>时遇到的各种问题与笔记 1. 初始不能降低Terrain的高度,需要到Terrain设置的第二个按钮中将Height从0调高 (注意:最 ...

  3. Adobe Acrobat XI Pro安装破解

    注册机使用说明: Install Instructions: (Read carefully!) 安装说明(仔细阅读!) 1. Disable your Network card or pull th ...

  4. 一个php类 Autoloader

    php autoloader: This is a class for PHP that keeps the user from having to manually include classes ...

  5. 初始化一台linux server来做项目管理和测试

    毕业以后很多没做过这么技术的事情了,不过今年要开始咯. Goal: 练手安装Nginx,并且配置不同的server,后端有Tomcat的(JIRA),有PHP(总得有的),还有Tornado和Node ...

  6. puppet&mcollective客户端安装

    一.环境: 1.客户端:            fedora 19 2.DnsServer:     192.168.0.160 3.server1.xxx.com(10.8.1.201):运行以下服 ...

  7. Poj2948Martian Mining(记忆化)

    链接 这题意好难懂 看得迷迷糊糊 想的也迷迷糊糊  后来睡了会突然想到了..不就是类似以前的矩阵操作 从右下角记忆化   大的由小的推来 dp[i][j] = max(dp[i-1][j]+s1,dp ...

  8. The Impact of Garbage Collection on Application Performance

    As we’ve seen, the performance of the garbage collector is not determined by the number of dead obje ...

  9. poj 2151 Check the difficulty of problems(概率dp)

    poj double 就得交c++,我交G++错了一次 题目:http://poj.org/problem?id=2151 题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 问 ...

  10. Web请求响应简单整理

      简单对Web请求响应如何处理进行的整理,难免有理解不到位,理解有偏差的地方,如有理解有误的地方,希望大牛批评指正. 1.Web开发的定义首先看看微软对Web开发的定义:Web开发是一个指代网页或网 ...