UITableView优化

内建方法:
重用:
cell
header
footer
在dataSource代理中实现的tableView:cellForRowAtIndexPath:方法
1.应尽可能快的返回重用cell实例,因为该方法会被每个cell调用一次。
2.不要在这里执行数据绑定,因为绑定了也没用,cell都还没在屏幕上显示
执行数据绑定,应在delegate代理的
tableView:willDisplayCell:forRowAtIndexPath:方法进行
保证cell在显示前存在数据
在delegate代理方法tableView:heightForRowAtIndexPath:
1.应该非常快地返回高度值,因为每个cell都调用一次
/*
错误使用例子:
在布局初始化cell实例并绑定数据后去获取它们的高度。
*/
总结:使用内建方法优化UITableView的正确方法:
1.重用cell实例:特殊类型的cell,应只有一个实例
2.不要在cellForRowAtIndexPath:方法中绑定数据,可以使用tableView:willDisplayCell:forRowAtIndexPath:方法进行数据绑定
3.快速计算cell高度。

更深一步:
UITableViewCell中的视图越多,滑动时FPS越低,
使用了手动布局和优化了高度计算后,问题就不在布局,而在渲染
cell必须快速被渲染:
应减少混合操作次数
在iOS模拟器上运行App,在模拟器的菜单中选择Debug,然后选中Color Blended Layers。
然后iOS模拟器就会将全部区域显示为两种颜色:绿色和红色。
绿色区域没有混合,但红色区域表示有混合操作。
通过这样子还可以发现有渐变的视图
如果cell视图backgroundColor不透明,那么系统在渲染视图会自带优化
所有没必要透明时应设置UIView的backgroundColor实现非透明
默认渲染由GUP负责,所有当设备需要执行很多混合操作时发生GPU满载,CPU却低负载
解决方案:
使用CPU进行渲染:
可以在UIView的drawRect:方法中使用CoreGraphics操作来执行CPU渲染
例如:
-(void)drawRect:(CGRect)rect{
[super drawRect:rect];
struct CGContext *context=UIGraphicsGetCurrentContext();
//background
CGContextSetFillColorWithColor(context, [UIColor groupTableViewBackgroundColor].CGColor);
CGContextFillRect(context, rect);
//text
CGRect textRect=[self bounds];
//line
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetLineWidth(context, 1.0);

CGContextStrokePath(context);

[str drawWithRect:CGRectIntegral(textRect) options:NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin attributes:@{
NSParagraphStyleAttributeName:@"name",
NSFontAttributeName:@"name",
NSForegroundColorAttributeName:@"name"
} context:NULL];
}
/*
这提高了渲染性能,不是因为CPU比GPU更快,
通过为让CPU来执行某些渲染任务,从而卸载GPU,因为在很多情况下,CPU可能不是100%负载的
优化混合操作的关键点是在平衡CPU和GPU的负载。
*/
总结:
1.减少iOS执行无用混合的区域:
不要使用透明背景,
需要使用渐变时尽量使用没有混合的渐变
2.优化代码,平衡CPU和GPU的负载
需要清楚知道哪部分使用GPU,哪部分可以使用CPU,以此保持平衡
3.为特殊的cell类型编写特殊的代码
像素获取:
出现不必要的子像素抗锯齿操作:
1.通过代码计算而变成浮点值的视图坐标
2.一些不正确的图片资源,这些图片的大小不是对齐到屏幕的物理像素上的(例如,你有一张在Retina显示屏上的大小为60*61的图片,而不是60*60的
通过在iOS模拟器上运行程序,在Debug菜单中选中Color Misaligned Image可以发现这类问题
1.粉红色区域会执行子像素渲染
2.黄色区域是图片大小没有对齐的情况。
代码中找到对应的位置:
使用手动布局,并且部分会自定义绘制,所以通常找到这些地方没有任何问题
所有建议自定义cell不要使用Interface Builder
解决方案:
为了解决这个问题,你只要简单地使用ceilf, floorf和CGRectIntegral方法来对坐标做四舍五入处理
总结:
1.对所有像素相关的数据做四舍五入处理,包括点坐标,UIView的高度和宽度
2.图片必须是像素完美的,否则在Retina屏幕上渲染时,它会做不必要的抗锯齿处理
异步UI:
带有媒体内容的cell:文本、图片、动画,甚至视频
所有这些都可能带有装饰元素:圆角头像,特定符号
因需要尽快返回cell,但圆角clipsToBounds很慢,图片需要从网络加载,需要在字符串中定位特定符号等问题
优化目标:
不要在主线程中执行这些操作:
优化方案:
1.在后台加载图片
2.在相同的地方处理圆角,然后将处理后的图片指定给UIImageView。
3.立刻显示文本,但在后台定位#号,然后使用属性字符串来刷新显示。
主要的思想是在后台执行大的操作
记住:需要尽快返回cell。
总结:
1.找到让你的cell无法快速返回的瓶颈
2.将操作移到后台线程,并在主线程刷新显示的内容
3.最后一招是设置你的CALayer为异步显示模式(即使只是简单的文本或图片)



1.UITableView只需要维护显示给用户的那些cell;
2.通过计算所有cell的高度之和来计算contentSize的值
3.不建议使用复杂的数学计算来获取cell的高度,如果可能,只使用加、减、乘、除
4.使用的子视图越多,AutoLayout的效率越低
5.UITableViewCell中的视图越多,滑动时FPS越低
6.平滑线段都使用子像素渲染技术来渲染,那你会让iOS执行一些不必要的任务,从而降低FPS

posted @ 2016-03-13 13:57  Jk_Chan  阅读(270)  评论(0编辑  收藏  举报