美文网首页
UITableView表格性能优化(一)

UITableView表格性能优化(一)

作者: philiha | 来源:发表于2017-08-19 23:26 被阅读0次

    作为一名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/

    相关文章

      网友评论

          本文标题:UITableView表格性能优化(一)

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