1. 用 ARC 治理内存
ARC(Automatic ReferenceCounting, 主动援用计数)和 iOS5 一起公布,它防止了最常见的也就是常常是因为咱们遗记开释内存所造成的内存泄露。它主动为你治理 retain 和 release 的过程,所以你就不用去手动干涉了。忘掉代码段结尾的 release 几乎像记得吃饭一样简略。而 ARC 会主动在底层为你做这些工作。除了帮你防止内存泄露,ARC 还能够帮你进步性能,它能保障开释掉不再须要的对象的内存。
iOS 开发交换技术群:563513413,不论你是大牛还是小白都欢送入驻,分享 BAT, 阿里面试题、面试教训,探讨技术,大家一起交流学习成长!
2. 尽量把 views 设置为通明
如果你有通明的 Views 你应该设置它们的 opaque 属性为 YES。
起因是这会使零碎用一个最优的形式渲染这些 views。这个简略的属性在 IB 或者代码里都能够设定。
Apple 的文档对于为图片设置通明属性的形容是:
(opaque)这个属性给渲染零碎提供了一个如何解决这个 view 的提醒。如果设为 YES,渲染零碎就认为这个 view 是齐全不通明的,这使得渲染系统优化一些渲染过程和进步性能。如果设置为 NO,渲染零碎失常地和其它内容组成这个 View。默认值是 YES。
在绝对比拟静止的画面中,设置这个属性不会有太大影响。然而当这个 view 嵌在 scroll view 里边,或者是一个简单动画的一部分,不设置这个属性的话会在很大水平上影响 app 的性能。
你能够在模拟器中用 Debug\Color Blended Layers 选项来发现哪些 view 没有被设置为 opaque。指标就是,能设为 opaque 的就全设为 opaque!
这里有一点须要留神,只有是有中文字符的 Label,哪怕你设置成不通明,模拟器中这个 Label 仍然会变红,这个猜想是字符绘制的时候出的问题,这个目前没找到好的解决办法。
3. 防止过于宏大的 XIB
iOS5 中退出的 Storyboards(分镜)正在疾速取代 XIB。然而 XIB 在一些场景中依然很有用。比方你的 app 须要适应 iOS5 之前的设施,或者你有一个自定义的可重用的 view, 你就不可避免地要用到他们。
如果你不得不 XIB 的话,使他们尽量简略。尝试为每个 Controller 配置一个独自的 XIB,尽可能把一个 View Controller 的 view 层次结构扩散到独自的 XIB 中去。
须要留神的是,当你加载一个 XIB 的时候所有内容都被放在了内存里,包含任何图片。如果有一个不会即刻用到的 view,你这就是在节约贵重的内存资源了。Storyboards 就是另一码事儿了,storyboard 仅在须要时实例化一个 view controller.
当家在 XIB 是,所有图片都被 chache,如果你在做 OS X 开发的话,声音文件也是。Apple 在相干文档中的记述是:
当你加载一个援用了图片或者声音资源的 nib 时,nib 加载代码会把图片和声音文件写进内存。在 OS X 中,图片和声音资源被缓存在 named cache 中以便未来用到时获取。在 iOS 中,仅图片资源会被存进 named caches。取决于你所在的平台,应用 NSImage 或 UIImage 的 imageNamed: 办法来获取图片资源。
这个问题我深有体会,用 xib 写的界面加载速度比间接用代码写的要慢好多
4. 在 Image Views 中调整图片大小
如果要在 UIImageView 中显示一个来自 bundle 的图片,你应保障图片的大小和 UIImageView 的大小雷同。在运行中缩放图片是很消耗资源的,特地是 UIImageView 嵌套在 UIScrollView 中的状况下。
如果图片是从远端服务加载的你不能管制图片大小,比方在下载前调整到适合大小的话,你能够在下载实现后,最好是用 background thread,缩放一次,而后在 UIImageView 中应用缩放后的图片。
5. 抉择正确的 Collection
学会抉择对业务场景最合适的类或者对象是写出能效高的代码的根底。当解决 collections 时这句话尤其正确。
一些常见 collection 的总结:
Arrays: 有序的一组值。应用 index 来 lookup 很快,应用 value lookup 很慢,插入 / 删除很慢。
Dictionaries: 存储键值对。用键来查找比拟快。
Sets: 无序的一组值。用值来查找很快,插入 / 删除很快。因为 Set 用到了哈希,所以插入删除查找速度比 Array 快很多
6. 关上 gzip 压缩
大量 app 依赖于远端资源和第三方 API,你可能会开发一个须要从远端下载 XML, JSON, HTML 或者其它格局的 app。
问题是咱们的指标是挪动设施,因而你就不能指望网络情况有多好。一个用户当初还在 edge 网络,下一分钟可能就切换到了 3G。不论什么场景,你必定不想让你的用户等太长时间。
减小文档的一个形式就是在服务端和你的 app 中关上 gzip。这对于文字这种能有更高压缩率的数据来说会有更显著的效用。
好消息是,iOS 曾经在 NSURLConnection 中默认反对了 gzip 压缩,当然 AFNetworking 这些基于它的框架亦然。像 Google App Engine 这些云服务提供者也曾经反对了压缩输入。
7. 重用和提早加载(lazy load) Views
更多的 view 意味着更多的渲染,也就是更多的 CPU 和内存耗费,对于那种嵌套了很多 view 在 UIScrollView 里边的 app 更是如此。
这里咱们用到的技巧就是模拟 UITableView 和 UICollectionView 的操作: 不要一次创立所有的 subview,而是当须要时才创立,当它们实现了使命,把他们放进一个可重用的队列中。
这样的话你就只须要在滚动产生时创立你的 views,防止了不划算的内存调配。
创立 views 的能效问题也实用于你 app 的其它方面。设想一下一个用户点击一个按钮的时候须要出现一个 view 的场景。有两种实现办法:
- 创立并暗藏这个 view 当这个 screen 加载的时候,当须要时显示它;
- 当须要时才创立并展现。
每个计划都有其优缺点。用第一种计划的话因为你须要一开始就创立一个 view 并放弃它直到不再应用,这就会更加耗费内存。然而这也会使你的 app 操作更敏感因为当用户点击按钮的时候它只须要扭转一下这个 view 的可见性。
第二种计划则相同 - 耗费更少内存,然而会在点击按钮的时候比第一种稍显卡顿。
8. 衡量渲染办法
在 iOS 中能够有很多办法做出丑陋的按钮。你能够用整幅的图片,可调大小的图片,或者能够用 CALayer,CoreGraphics 甚至 OpenGL 来画它们。当然每个不同的解决办法都有不同的复杂程度和相应的性能。
简略来说,就是用当时渲染好的图片更快一些,因为如此一来 iOS 就免去了创立一个图片再画货色下来而后显示在屏幕上的程序。问题是你须要把所有你须要用到的图片放到 app 的 bundle 外面,这样就减少了体积–这就是应用可变大小的图片更好的中央了: 你能够省去一些不必要的空间,也不须要再为不同的元素 (比方按钮) 来做不同的图。
然而,应用图片也意味着你失去了应用代码调整图片的机动性,你须要一遍又一遍一直地重做他们,这样就很浪费时间了,而且你如果要做一个动画成果,尽管每幅图只是一些细节的变动你就须要很多的图片造成 bundle 大小的一直增大。
总得来说,你须要衡量一下利弊,到底是要性能能还是要 bundle 放弃适合的大小。
9. 解决内存正告
一旦零碎内存过低,iOS 会告诉所有运行中 app。在官网文档中是这样记述:
如果你的 app 收到了内存正告,它就须要尽可能开释更多的内存。最佳形式是移除对缓存,图片 object 和其余一些能够重创立的 objects 的 strong references.
侥幸的是,UIKit 提供了几种收集低内存正告的办法:
在 app delegate 中应用 applicationDidReceiveMemoryWarning: 的办法
在你的自定义 UIViewController 的子类 (subclass) 中笼罩 didReceiveMemoryWarning
注册并接管 UIApplicationDidReceiveMemoryWarningNotification 的告诉
一旦收到这类告诉,你就须要开释任何不必要的内存应用。
例如,UIViewController 的默认行为是移除一些不可见的 view,它的一些子类则能够补充这个办法,删掉一些额定的数据结构。一个有图片缓存的 app 能够移除不在屏幕上显示的图片。
这样对内存警报的解决是很必要的,若不器重,你的 app 就可能被零碎杀掉。
然而,当你肯定要确认你所抉择的 object 是能够被重现创立的来开释内存。肯定要在开发中用模拟器中的内存揭示模仿去测试一下。
当然,当初 iOS 设施运行内存越来越大,这一点很难呈现了
10. 应用 Sprite Sheets
Sprite sheet 能够让渲染速度放慢,甚至比规范的屏幕渲染办法节俭内存。
11. 防止重复解决数据
许多利用须要从服务器加载性能所需的常为 JSON 或者 XML 格局的数据。在服务器端和客户端应用雷同的数据结构很重要。在内存中操作数据使它们满足你的数据结构是开销很大的。
比方你须要数据来展现一个 table view, 最好间接从服务器取 array 构造的数据以防止额定的两头数据结构扭转。
相似的,如果须要从特定 key 中取数据,那么就应用键值对的 dictionary。
这一点在解决大量数据的时候极为重要,用空间换工夫的办法兴许是极好的。
12. 抉择正确的数据格式
从 app 和网络服务间传输数据有很多计划,最常见的就是 JSON 和 XML。你须要抉择对你的 app 来说最合适的一个。
解析 JSON 会比 XML 更快一些,JSON 也通常更小更便于传输。从 iOS5 起有了官网内建的 JSON deserialization 就更加方便使用了。
然而 XML 也有 XML 的益处,比方应用 SAX 来解析 XML 就像解析本地文件一样,你不需像解析 json 一样等到整个文档下载实现才开始解析。当你解决很大的数据的时候就会极大地减低内存耗费和减少性能。