工大助手Tableview优化

作者 汪小祯 日期 2017-03-10
工大助手Tableview优化

寒假的时候写完了iOS端的校园说说部分,因为当时技术有限,很多部分不完善,尤其体现在高速滑动时,界面卡顿很严重。开学大概一个月时,自己技术也有了一定提高,对tableview进行了重构,并在这里写下思路。

老版本

因为当时只会使用xib+tableview,所以用了一个很取巧的地方。
一个说说模块,因为高度等问题,我实际上是由于四个row部分组成的。
见下图红框部分。
IMG_0480

实现方式

每条说说采用了4个不同的xib文件和tableViewCell来实现,分别对应四个红框

第一个红框

在这个部分是固定的头像,昵称,以及学号,这个部分不用进行任何高度适配,是最简单的。

第二个红框

这个部分是文本内容,这里需要根据行数进行高度适配,而当文本高度改变后,因为在xib界面中设置了Autoresizing,所以文本自然也会继续充满

第三个红框

这里显示说说的评论数目,因为也是固定的尺寸,所以不需要更改

第四个红框

这里也需要适配高度,每加入一行都要适配一次。

问题所在

正如上述所说的,这种方式在第一次初设计时只考虑使用效果而没有考虑到运行效率,在后来的用户反馈中,我开始重视这个问题,并使用Instruments进行测试
性能测试从一进入界面起就开始不停的往下滑,那么利用YYFPS测试到了的结果如下
FPS未优化
可以看到在满帧数为60的真机测试中,平均FPS只有30左右。
我接着开始测试每条代码运行时间
未优化加载方式2
同样可以看到在代码加载中消耗了大量的时间。

我对此的思考

在优化中,我尝试了很多方式,但我发现最关键的问题FPS的帧数还是没有解决,思考后,研究了VVeboTableViewDemo,决定自己用代码重构一遍校园说说

重构后

先放界面
IMG_0528
再者放FPS测试图
加入按需加载
测试结果如上,可以看到在高速滑动中,FPS从之前的30左右已经提升到50左右。下一步我从加载图片中的方式入手,这样如果在高速滑动中不加载图片,只在低速或者点击屏幕时加载平均FPS可以达到55.

优化过程

TableVie
首先我新建了两个Model类,分别用来处理说说的数据,和评论的数据
从主界面进入到说说界面,首先会从MomentsViewController的viewDidLoad方法,加载momentsTableView类

momentsTableView = [[MomentsTableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
[self.view addSubview:momentsTableView];

在momentsTableView初始化中会调用[self loadData:JSONDic];方法,加载之前使用get请求从服务端得到了说说数据,接着将每组数据传给MomentsCell,并调用其draw方法绘制界面

- (void)drawCell:(MomentsCell *)cell withIndexPath:(NSIndexPath *)indexPath{
MomentsModel *data = [datas objectAtIndex:indexPath.section];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.LikesData = likeDatas;
cell.data = data;
[cell draw];
[cell loadPhoto];
}

关于高度适配的问题,因为是在momentsTableView的初始化方法中用Model解析了数据,在数据解析的时候,我也一并在Model中计算了每条说说的高度,所以在heightForRowAtIndexPath方法中,我直接可以设置好每行的高度,在方法中也不用进行逻辑判断高度

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
MomentsModel *momentsModel=datas[indexPath.section];
return SYReal(70)+momentsModel.textHeight+momentsModel.photoHeight+SYReal(40)+momentsModel.commentsHeight;
}

关于不同屏幕大小的问题,我用了一个宏,会以iphone 6plus屏幕分辨率为基准进行计算

#define SYReal(value) ((value)/414.0f*[UIScreen mainScreen].bounds.size.width)

后续的想法

虽然优化达到了自己满意的效果,但是觉得知识体系上还有很多欠缺,主要集中在多线程GCD等方式中,还不能达到稳定60FPS的效果,争取在知识有一定积累后再来进行优化。

工大助手源代码