iOS:关于UITableView的性能优化点

2015年最后一天,来总结一下iOS开发中遇到过的性能大坑,特别是UITableView这一用途非常广泛的控件。

一个UITableView为展示主题的app遇到的问题大概分为这几类:1、滚动卡顿。2、滚动没有明显卡顿但是掉帧。3、滚动崩溃。现就我开发中遇到的这些问题提出一些可能可以解决问题的地方。


导航:

1 滚动卡顿

1.1 主线程网络资源拉取冻结UI

1.2 cellForRowAtIndexPath委托中消耗CPU时间

1.3 UITableViewCell中包含大量UIImageView或其他图片容器直接加载了UIImage

1.4 Cell动态高度

2 滚动掉帧

2.1 CALayer的maskToBounds属性

2.2 Cell中太多UIView或者太多透明元素

3 滚动崩溃



1 滚动卡顿

1.1 主线程网络资源拉取冻结UI

这个问题属于老生常谈了。

解决方法:子线程下载调用主线程刷新UI。多线程现在主要用NSOperation和GCD(除了这两个还有个古老的NSThread)。NSOperation能更好的管理线程;GCD能巨方便的执行异步代码,但是管理并不方便。用法自行查看API文档。

1.2 cellForRowAtIndexPath委托中消耗CPU时间

查看UITableViewDataSource的cellForRowAtIndexPath委托是否做了太多事,或读取了较大的磁盘文件例如兆字节级别的文件,或者做了某些大量消耗CPU时间的事情例如计算兆字节级别的NSData的MD5值等,这些会在滚动过程中系统调用委托时冻结UI造成卡顿。

解决方法:把这些事情放到子线程去做。

1.3 UITableViewCell中包含大量UIImageView或其他图片容器直接加载了UIImage

这个因素经常会被开发者忽略,当UIImage赋给UIImageView的image属性时系统需要做位图解码、字节对齐、缩放适应UIImageView的contentMode等等事情。如果你的Cell中包含未压缩的大图例如几千乘几千的图片出现卡顿,可以考虑从这方面入手。

解决方法:子线程UIImage位图解码,后台绘制,且只绘制UIImageView中应该显示的大小避免缩放等。

如果这样还不能解决问题,考虑使用CALayer等轻量级控件绘制图片。CALayer不用响应用户操作,因此会带来一定的性能提升。此方法同样适用与用CALayer绘制文字代替使用UILable。

1.4 Cell动态高度

这个问题我自己开发中并没有遇到过。解决上述几个问题之后基本能解决卡顿问题,若以上处理还不能解决时可以考虑Cell动态高度计算的问题。

网络上的解决方法:缓存行高。

2 滚动掉帧

2.1 CALayer的maskToBounds属性

例如我需要在UIImageView中显示头像,这个头像是圆形的,但是我的图片是方形的。于是我设置imageView.layer.cornerRadius值改变了imageView的bounds,然后设置imageView.layer.maskToBounds = true去遮罩出圆形的头像。这样操作是没有问题的,但是千万注意,这个imageView不能放在Cell里,或者放在UIScrollView里。一旦滚动容器里有UIView设置了maskToBounds属性,你的噩梦就到来了。屏幕内存在1个设置过maskToBounds的UIView或许没感觉,2个,3个,你会很明显地发现,整个世界都变卡了。

解决方法:不设置maskToBounds属性,需要圆角图片可以事先在子线程离屏绘制然后缓存起来。

2.2 Cell中太多UIView或者太多透明元素

GPU像素填充率有限,大量透明半透明元素GPU需要重复填充,势必造成压力。

解决方法:减少透明元素,使用CALayer等轻量级控件代替UIView。

3 滚动崩溃

这个问题通常出现在数据源。滚动过程中访问了不存在的数据源出现的崩溃或其他问题。从网络拉取的数据解析之后生成Array供UITableView使用,在修改了Array以后,请务必立即在主线程reloadTableView,以免出现越界等错误。


作为完全自学的开发者,当学习到一定程度以后,掌握UIKit的基本用法以后,向着更底层的性能问题研究进军我认为是个必然,也很庆幸自己自然而然地迈出了这一步。2015年最后一天,希望2016一切顺利。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值