美文网首页
UITableView的优化

UITableView的优化

作者: 六横六竖亚 | 来源:发表于2017-09-05 17:28 被阅读10次

UITableView无疑是iOS开发中最重要的控件,它的优化直接牵扯到性能和体验,虽然所有优化的基础核心思想都大同小异,但博客鱼龙混杂众说纷纭,各类技巧也是层出不穷看起来都很有道理,于是决定按照自己的理解全面总结一下,便于记忆和重温。

最基础的Cell复用

dequeueReusableCellWithIdentifier,通过Identifier复用。给UITableView添加拓展方法简化cell的复用方法。如下:

- (UITableViewCell*)loadXibCellWithIdentifier:(NSString*)cellIdentifier {

       UITableViewCell* cell = [self dequeueReusableCellWithIdentifier:cellIdentifier];

       if (nil == cell) {  

            UINib *nib = [UINib nibWithNibName:cellIdentifier bundle:nil];

            [self registerNib:nib forCellReuseIdentifier:cellIdentifier];

            cell = [self dequeueReusableCellWithIdentifier:cellIdentifier];

        }

        return cell;

}

算高

由于算高函数heightForRowAtIndexPath是代理中调用超级频繁的函数,所以,提前算高,并将高度缓存在数据源中是很有必要的。而在iOS8以上提供了设置estimatedRowHeight估算高度后根据cell的自动布局自动高度的方法虽然极度方便(甚至不用实现高度回调函数),但其性能却不容乐观,特别是由于xib的加载是首次加载便全控件加载。

但是如果你的项目已经使用了sb或xib,UITableView+FDTemplateLayoutCell从run loop的角度提供了很优秀的解决方案。

图片缓存

图片大多使用SDWebImage所以图片的内存缓存和硬盘缓存都是默认完成的。

富文本和圆角

两个不可触碰的禁区,代价极其昂贵。

子控件和绘制

subviews自然是越少越好,而且要尽量不透明(即Color Blended Layer选中后的红色区域越少越好)。当遭遇复杂页面的性能瓶颈,用drawRect或其他方法实现控件的全面异步绘制是很好的选择,但这就要求舍弃xib和storyboard,而且布局方面也变得不是十分方便了。

UIGraphicsBeginImageContextWithOptions(rect.size,YES,0);  //创建基于位图的上下文

CGContextRefcontext =UIGraphicsGetCurrentContext();  //获取上下文

[[UIColorcolorWithRed:250/255.0green:250/255.0blue:250/255.0alpha:1]set];  //背景色设置

CGContextFillRect(context, rect);  //背景色填充

[testString drawInContext:context withPosition:CGPointMake(x, y) andFont:font andTextColor:color andHeight:rect.size.height];  //简单文字绘制

[testImage drawInRect:CGRectMake(x, y, w, h) blendMode:kCGBlendModeNormal alpha:alpha];  //简单图片绘制

最变态的VVeboTableViewDemo

来自于github上一个2k+star的demo,其核心优化思想是:1、异步将内容渲染成图片;2、依照滑动速度,按需加载滚动目标位置前后指定三行的cell。

解读与记录

首先是算高。当获取到数据源之后,应根据数据源和视图布局规则计算出整个cell的frame,用于绘制时的大背景和heightForRowAtIndexPath函数;计算其他可变高度(如textframe)。

然后需要分解cell的布局,基本固定的控件和内容应绘制在一张图片中(如昵称,时间,点赞数等元素),主要使用[string/image drawInRect]的绘制方法(demo中的富文本绘制使用了极度复杂的drawInContext扩展方法,可能是为了兼容iOS8以下)。

而特殊的控件则需要单独处理,如头像(使用白边的中心镂空的蒙版,解决圆角问题),如附图(scrollview),内容(未使用Label,使用以View为基类封装了绘制方法的自定义控件VVeboLabel,具有颜色字体行间距对齐方式等功能,还提供了超链接点击事件(但实现方式过于变态)。

而cell暴露给tableview的属性有数据源字典/模型,接口有draw,clear,releaseMemory(移除时候使用),cellForRowAtIndexPath函数中先调用cell的clear,再赋值data和draw。

最后,依照滚动速度按需加载。scrollViewWillEndDragging委托函数中,根据targetContentOffset和velocity判断需要跳过和需要加载的row,存入needLoadArr用于加载。

相关文章

网友评论

      本文标题:UITableView的优化

      本文链接:https://www.haomeiwen.com/subject/pqpejxtx.html