UITableView表格性能优化(一)

作为一名iOS开发程序员,你肯定能写出TableView..但是这个TableView的性能到底怎么样呢...那就那就仁者见仁智者见智了..
网上的文章一抄一大把.在这里作为一个彩笔的我...也给几条建议吧...

1.cornerRadius

imageView.layer.cornerRadius = 10;
imageView.clipsToBounds = YES;

相信小伙伴们对cornerRaius并不陌生,如果在iOS8之前,在表格视图中如果频繁大量使用cornerRaius,就可能会对表格的性能产生影响...

15060063301952.jpg
15060092904512.jpg

你会发现,视图中用了cornerRaius的部分是红色的...
可能单单这样一个视图没什么问题,但是如果在tableView中会怎么样...
在每个单元格中可能就会对性能产生一定的影响了...
为什么会影响呢?是因为苹果对裁切做了透明效果的处理,混合模式变红就是一个很好的说明,而这个alpha可能会对性能造成影响...
但是据说iOS8之后苹果对cornerRaius做了优化,理论上说对性能的影响降低了....
但是还是感觉很不爽啊....
所以咱们还是自己开启图形上下文自己画把....
自己动手丰衣足食....

// UIImage 分类方法
- (instancetype)jb_circleImage {
    // 开启图形上下文   opaque 一定要写YES 表示不透明
    UIGraphicsBeginImageContextWithOptions(self.size, YES, 0);
    // 范围
    CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);  
    // 填充颜色<这里的颜色就你来定拉~~>
    [[UIColor whiteColor] setFill];
    UIRectFill(rect);
    // 裁剪
    [[UIBezierPath bezierPathWithOvalInRect:rect] addClip];
    // 绘制图片到圆上面
    [self drawInRect:rect];
    // 获得图片
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    // 结束图形上下文
    UIGraphicsEndImageContext();
    return image;
}
15060090974778.jpg

亲爱的小伙伴,是不是看到绿色就舒服多了....
如果你说反正也这个颜色也不在头上我也没办法...
谁让它不是王宝绿呢...
上面那个分类方法我是用贝塞尔路径切的,如果用上下文切也是可以的,调用CGContextClip(context)这个小函数,不过要多获取一下上下文~

2.缓存Cell的行高

各位小伙伴,如果你遇到Cell高度不同的时候是怎么处理的呢,相信老程序员们都还记得木有自动布局的那一段用frame计算行高的轻松的时刻....
而后来,我们有了AutoLayout,仅仅是因为苹果的机型变多了,从iPhone4,5,6,6+,iPadAir,Pro....
各种各样的机型层出不穷,为了适配我们不得不选择更为牛X的AutoLayout...
最开始我们用Autoresizing,然后苹果让我们用原生的那一长串布局,然后苹果发现那一串真的很长,于是出了VFL,然后发现VFL不太友好,又出了LayoutAnchors,但是最后我们选择了Masonry/SnapKit.....
大部分小伙伴还是用Masonry的....吧.....
虽然不更新了.....
其实用Masonry真的是非常的简单加方便,相信用过的小伙伴们都会说好....
But用自动布局来计算行高真的真的是非常消耗CPU,因为表格发生滚动行高就要进行计算,这是和之前用frame来计算行高是截然不同的,别看你只写了两句话(貌似第二句也不用写了,那么就一句话)...

self.tableView.estimatedRowHeight = 100;
self.tableView.rowHeight = UITableViewAutomaticDimension;

系统在后台要一直帮你拼命的计算行高啊啊啊啊啊!!!!!!
然后稍微不注意就会出现控制台发生警告,那一坨坨是不是看了都想死....
不过没关系,那个只要调整一下最后一条和contentView的约束的优先级<调低一点>(或者疯狂的用lessThan,greaterThan)就OK了...扯远了...
我们的话题是!!这样很消耗CPU啊啊啊啊.....
你想想:用户正在用你的APP滚动表格,也许他就是想浏览一下,就那么滚啊滚,结果电量掉的嗖嗖的,手机还发烫,那么你说你亲爱的用户会干嘛?给你打个电话?告诉你:亲爱的,你的表格滚起来有点烫手哦~~~~~~呵呵呵呵呵,碰到傲娇一点的就直接给你卸载了好不好....
好吧..扯了这么多没用的那么我们来说说解决办法吧...
那就是:缓存行高..
tableView有这么一个代理方法:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

默认的情况下每个Cell会调用3次(貌似Xcode版本不一样这个值也不尽相同),是不是很惊悚,假如每个Cell都用自动布局,每个Cell系统都要忙碌的计算三次,表格能不卡吗.....
它的原理是这样的:
1.假如你没有设置预估行高呢,每个Cell都先计算一次,然后再计算你显示行的高度,一直到Cell能够填满你目前的屏幕,同时更新contentSize这样你就能滚了,哦,不..你的表格又能愉快的滚动了...
2.如果你设置了预估行高呢,那么系统会根据你设置的预估行高计算一下contentSize;至于你计算多少次也是根据你设置的预估行高来的,直到填满你的手机屏幕,更新contentSize;你要是给太大的预估行高,超出了预估的范围,她会顺序的计算后面的行高,一直到填满屏幕...
3.怎么说呢,使用预估行高在每个Cell的显示之前都需要计算,所以单个Cell的效率略低,但是整体的效率提高了啊.....
4.所以预估行高你别瞎给,尽量给的稍微准点....

言归正传.要怎么做呢
在这里我介绍两个方法
方法一: 用别人写好的第三方库,至于用什么就自行去谷歌或者GitHub上面搜索吧
方法二: 自己缓存.
如果你用MVC开发呢,就在你的模型属性中定义一个专门用来存储行高的属性,如果你用MVVM开发呢,那么就在你的视图模型中定义一个存储行高的属性(貌似我是在写废话......)
然后你再heightForRowAtIndexPath那个方法里面创建一个Cell<一定要用alloc/init创建,从缓存池中取会造成死循环,至于为什么自己去想!!!>,然后你把你的模型数据赋值给它,然后重头戏来了你要调用一下这个方法:[self layoutIfNeeded];从而Cell提前计算约束!提前计算约束!提前计算约束!
有了约束你就能获得最大的Y了,有了最大的Y,行高就缓存上了

在你的Cell里面添加一个这个方法

- (CGFloat)calculateRowHeight:(XXModel *)yourModel {
    self.model = yourModel;
    
    [self.view layoutIfNeeded];
    
    return CGRectGetMaxY(你最下面控件.frame);
}

最后你再heightForRowAtIndexPath里面返回的行高就是你计算出来的行高了,这样只用计算一次就可以了,并且还作为属性缓存起来,大大节省了CPU的开销....

最后的最后......假如你是ibireme的粉丝的话,他的一篇文章可以拜读一下,好吧我承认写的比我深刻多了........https://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容