• iOS 性能优化套路


    ***

     一级套路

    ***

     使用ARC管理内存
    - 防止内存泄露
    - 保证释放掉不再需要的内存,提高性能

    在正确的地方使用 reuseIdentifier
    平时接触的需要考虑重用的视图有UICollectionView,UITableView。需要考虑它们内部的cell,header,footer。
    CollectionView和TableView原理相似,内部存在着两个容器对象,分别是:
    - 当前展示视图容器,里面是当前展示的cell,footer,header
    - 可重用视图容器,里面是带有重用标识符的cell,footer,header

    尽量把View设置为完全不透明
    需要将View属性opaque设置成YES
    当opaque设置成NO时,app在进行图片展示时,会让图片处理器(GPU)进行图像混合计算(blending操作)。
    图片处理器会将透明View的像素与它相临的像素点相加,重新计算出一个新的像素值。如果app带有动画,滚动效果,性能会受到明显的影响。

    避免过于庞大的XIB
    XIB是推出比较早的绘图工具,后面在iOS5的时候推出了StoryBoard来取代XIB的地位。不过到目前它们两个是共存的状态,原因是它们的适用场景不同。
    - XIB使用子View控件的定制,偏小型。但是在使用时会将整个XiB都加载到内存,如果XIB过大的话,会导致内存浪费。
    - StoryBoard是偏重宏观的,一般做控制器跳转,可以定义整个控制器视图。在使用时,StoryBoard是用到哪个控制器加载哪个,不会将所有的都加载。

    严格要求对主线程的使用
    主线程是用户对app的直接体验,所有的交互都是靠主线程接受和反馈的。终于程度可见一斑。所以需要把++耗时的操作都移动到子线程++去,等有了结果再切换回主线程来。

    避免在Image Views中调整图片大小
    如果给予==UIImageView==的image的尺寸不合适,那么==UIImageView==就需要对image进行自动缩放,这个缩放操作是比较耗费资源的。对于从网络加载后需要滚动的,动画的==UIImageView==影响更大。所以image和==UIImageView==的尺寸尽量匹配。匹配方式:

    - 要求切图尺寸符合要求
    - 将获得的图片在本地缩放规定的尺寸后,再返回给==UIImageView==

    根据业务场景选择合适的集合(不同的数据结构)
    - 数组(增删慢;改查快):有序集合,存储在一段连续的内存空间,可方便利用下标查看,增加删除都会让后序元素整体移动
    - Set(增删改查快) :无序集合,添加重复的对象会自动覆盖掉前面的,做到整个集合只有一份
    - 字典(增删改查快):健值集合,可根据key对应操作value

    合理使用gzip
    在网络请求时,若数据比较大,可考虑采用压缩格式,提高用户体验

    ***
     二级套路
    ***

    重用view和懒加载view
    - 对于重复出现的子View,考虑模仿tableview的重用机制
    - 对于不一定使用的子view,考虑使用懒加载机制(懒加载是牺牲体验提高性能)

    重视缓存
    缓存的种类很多,主要按情况来进行缓存,如下所示:
    - 创建麻烦而经常使用(比如NSDateFormatter和NSCalendar),对于这样的对象缓存,可以放在单例或者类属性上。对频繁时提供性能有大的改变。
    - 请求麻烦而资源不经常改变(网络请求),
    - 频繁计算而结果不变的(tableview的行高)

    图片渲染方式选择
    - 使用UI给的切图,渲染快,效率高。但是bundle体积大。
    - 使用CoreGraphics,UIBezir曲线进行代码绘制,消耗性能。但是减少bundle体积

    内存警告处理
    系统提供了不少处理内存警告的方式,在受到内存经过时释放一些可以重建的对象,可以提供app的稳定性,它们适用多种场景:
    AppDelegate中的
    `applicationDidReceiveMemoryWarning: `
    UIViewController类中的
    `didReceiveMemoryWarning`
    系统提供的通知
    `UIApplicationDidReceiveMemoryWarningNotification`

    避免在内存中频繁转换数据结构
    尽量使后台返回的数据结构与app场景使用的一致,并选择合适的容器保存。
    Array,Dictory,Set,根据数据使用的特性,进行合理选择。

    View背景设置的方案选择
    - 小图平铺
    ```
    self.view.backgroundColor = [UIColorcolorWithPatternImage:[UIImageimageNamed:@"background"]];
    ```

    - 全图背景

    ```
    BuilderUIImageView*backgroundView = [[UIImageViewalloc] initWithImage:[UIImageimageNamed:@"background"]];[self.view addSubview:backgroundView];
    ```

    选择适当的方式为shadowPath赋值
    在开发中经常需要给View、Layer设置隐形,常见的设置方式有两种

    - 通过属性设置

    ```
    // Setup the shadow ...
    UIView*view = [[UIViewalloc] init];
    view.layer.shadowOffset=CGSizeMake(-1.0f,1.0f);
    view.layer.shadowRadius =5.0f;
    view.layer.shadowOpacity =0.6;
    ```
    这种方式需要Core Animation在后台提前根据图像frame计算出图像和阴影。增加了计算操作,消耗性能。

    - 通过贝塞尔曲线赋值
    ```
    view.layer.shadowPath = [[UIBezierPath bezierPathWithRect:view.bounds] CGPath];
    ```
    由于路径是指定好的,无需再次计算,提高了性能。

    TableView优化方案
    1.reuseIdentifier规范使用,cell,header,footer。
    2.view的opaque为YES,避免色素计算
    3.避免cell中图片缩放
    4.耗时任务子线程处理,避免阻塞主线程(网络请求,数据处理)
    5.减少subviews的层级
    6.用贝塞尔曲线设置阴影路径
    7.尽量避免代理赋值(tableview直接设置rowHeight, sectionFooterHeight 和 sectionHeaderHeight)
    8.cell动态行高时,预先计算并存储,提高性能

    数据持久化方案
    1.NSUerDefaults:相当于电脑中的偏好设置
    2.plist:存储简单列表(城市对应的邮编列表)
    3.归档:需要实现NSCoding协议
    4.SQLite、Realm:大数据的存储方案

    ***
    三级套路
    ***

    提高App启动时间
    1.异步处理耗时任务(网络加载,数据库访问,批量预处理)
    2.避免大规模内存加载(大体积xib加载)
    3.主要看门狗问题

    合理使用Autorelease Pool
    对象过了作用域,引用计数会自动减一。如果在作用域中突然大量建对象,则内存会直线下降。这中情况下要适量加Autorelease Pool,进行及时释放
    合理使用图片的加载方式
    1.小体积而重复使用的图片,用imageNamed,此时图片对象会保存在内存中
    2.大体积而不长用的图片,用imageWithContentsOfFile,图片每次都是从本地加载。不缓存

  • 相关阅读:
    word2vec层次化softmax理解
    python动态加载模块,并获取模块中的类与方法(类似反射)
    用Python装饰器给函数自动加上try except
    3D打印第二弹:狗牌
    【高等代数】06
    【高等代数】05
    沙箱-guacamole
    关于写博客的一点思考
    二阶段目标检测总结
    Waymo object detect 2D解决方案论文拓展
  • 原文地址:https://www.cnblogs.com/zhou--fei/p/9898683.html
Copyright © 2020-2023  润新知