V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tunnyios
V2EX  ›  iOS

iOS 性能优化~使用或接触过的皮毛分享

  •  
  •   tunnyios · 2016-05-22 20:38:55 +08:00 · 2234 次点击
    这是一个创建于 2893 天前的主题,其中的信息可能已经有所发展或是发生改变。

    欢迎关注我的 Blog tunnycoder.com

    iOS 性能优化~使用或接触过的皮毛分享

    虽然 iPhone 性能越来越好,但是 App 也越来越复杂,所以性能问题也从来都是移动开发者所关心的问题之一。一个 App 性能好的表现主要是在:应用启动快速、 UI 反馈响应及时、列表滚动操作流畅、内存使用合理,更不能随随便便 Crash 。

    常见性能优化技巧与策略

    网上有一大堆性能优化的 Tips ,宗旨是写代码之前规避一些性能问题,时常对代码进行性能方面的提升,列出一些个人碰到过的。

    1. Core Foundation框架的东西,无论是ARC或者非ARC 手动创建的数据类型,都需要手动释放
    2. 善用重用和延迟加载
    • 像 tableView 一样,不要一下子创建所有的 subViews ,在需要的时候再创建、将 view 放到一个可重用的列表中。这样只需要在滚动发生时创建你的 views ,避免了不划算的内存分配; 重用一些创建初始化需要重大开销的对象,通过添加属性到你的 class 里或者创建静态变量来实现。NSDateFormatterSQLite 语句正则表达式的初始化和设置都很昂贵。
    1. 尽量把 views 设置为不透明即 opaque 属性为 YES 。
    • (opaque)这个属性给渲染系统提供了一个如何处理这个 view 的提示。如果设为 YES , 渲染系统就认为这个 view 是完全不透明的,这使得渲染系统优化一些渲染过程和提高性能。如果设置为 NO ,渲染系统正常地和其它内容组成这个 View 。默认值是 YES 。
    1. 避免过于复杂的 xib 文件
    • 当加载一个 xib 的时候所有内容都被放在了内存里,包括任何图片。如果有一个不会即刻用到的 view ,就是在浪费宝贵的内存资源了。 Storyboards 就是另一码事儿了, storyboard 仅在需要时实例化一个viewController.
    1. 尽量避免阻塞主线程
    • UIKit 在主线程上做所有工作,渲染,管理触摸反应,回应输入等都需要在它上面完成。界面卡顿就是主线程被阻塞的表现。尽量把耗时操作放到其他线程中来做,然后回到主线程来刷新界面。大部分耗时操作牵涉到读写外部资源的 I/O 操作,比如存储(读写文件)或者收发网络数据。可以使用 GCD 来进行多线程操作的,但是一个 App 的线程最好不要超过 5 条。原因 CPU 会在 N 条线程之间调度,消耗大量 CPU 资源; 每条线程被调度执行的频次会降低(线程的执行效率降低)
    • 为了得到更流畅的交互体验, iOS 已经将很多事情放到了其他线程中去做,比如:View 和 layer 的动画绘制前的计算Layer 的组合计算( drawing 后的叠加)PNG 的解码
    1. Cache 缓存
    • 善用缓存,缓存一些经常要使用的,不易改变的。比如一些整个 App 都需要用的模型对象,或者一些计算数据。
    1. 权衡渲染方法(又一个性能与空间的权衡)
    • 使用事先渲染好的图片会对性能更好一点,但是图片很多会增加 bundle 的大小;但是如果在代码中不断修改某张图用作不同的用途,会给 App 增加性能负担,所以利弊就有你自己来权衡咯
    1. 内存警告处理
    • 如果你的 app 收到了内存警告,它就需要尽可能释放更多的内存。最佳方式是移除对缓存,图片 object 和其他一些可以重创建的 objects 的 strong references.
    • UIKit 提供了几种收集低内存警告的方法: (一旦收到这类通知,你就需要释放任何不必要的内存使用)
    1. AppDelegate中使用applicationDidReceiveMemoryWarning:的方法
    2. 在你的自定义 UIViewController 的子类(subclass)中覆盖didReceiveMemoryWarning
    3. 注册并接收UIApplicationDidReceiveMemoryWarningNotification 的通知
    • 例如, UIViewController 的默认行为是移除一些不可见的 view , 它的一些子类则可以补充这个方法,删掉一些额外的数据结构。一个有图片缓存的 app 可以移除不在屏幕上显示的图片。
    • 例如,当整个项目的 image 都由 SDWebImage 来处理,可能 SDWebImage 越来越大,因此需要在任何一个控制器存在内存警告时,做清理操作。清理操作要在 Appdelegate 里面做:1.取消正在下载的操作 2.清除内存缓存

    App 性能的关注点

    本文针对用户响应内存方面,简单介绍一下如何进行性能分析。 用户响应 用户响应即用户事件被 runloop 及时处理和响应。 runloop 其实就是 App 事件驱动的一个大循环,使程序一直运行,并接受用户输入。它有一个事件队列,决定程序在何时处理哪些事件, runloop 中通过消息队列防止出现主调方一直等待的情况。 runloop

    3 条回复    2016-05-24 20:02:04 +08:00
    xjbeta
        1
    xjbeta  
       2016-05-22 20:44:02 +08:00
    差评 编号怎么都是 1
    tunnyios
        2
    tunnyios  
    OP
       2016-05-22 21:04:39 +08:00
    @xjbeta 抱歉😂刚刚重新修改了一下序号😅
    simon4761
        3
    simon4761  
       2016-05-24 20:02:04 +08:00
    都是比较老话常谈的优化点了,希望你自己能总结出来一些正规点的优化手段 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5265 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 09:20 · PVG 17:20 · LAX 02:20 · JFK 05:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.