总结了IOS性能优化25点

性能是每一位程序员都应该正视的问题,对 iOS 应用的开发尤其重要,如果你的应用崩溃,假死或者卡慢,那么你的产品将会失去很多用户,appstore的差评满天飞,做出一个失败的产品是每一位工程师的痛。然而由于iOS设备的限制,有时搞好性能是一件难事。开发过程中你会有很多需要注意的事项,也很容易在编写代码时忘记考虑性能影响。

为了自己注意性能问题,同时也给各位同行参考,我整理了互联网上很多性能优化的事项。这篇文章以一个方便查看的核对表的形式整合了可以用来提升app性能的25条建议和技巧。

注意:在优化代码之前,你都要注意一个问题,不要养成”预优化”代码的错误习惯。时常使用Instruments去profile你的代码来发现需要提升的方面。Matt Galloway写过一篇很棒的如何利用Instruments来优化代码的文章。

还要注意的是,这里列出的其中一些建议是有代价的,所建议的方式会提升app的速度或者使它更加高效,但也可能需要花很多功夫去应用或者使代码变得更加复杂,所以要仔细选择。

目录

我要给出的建议将分为三个不同的等级: 入门级、 中级和进阶级:

入门级(这是些你一定会经常用在你app开发中的建议)

1. 用ARC管理内存

2. 在正确的地方使用reuseIdentifier

3. 尽可能使Views透明

4. 避免庞大的XIB

5. 不要block主线程

6. 在Image Views中调整图片大小

7. 选择正确的Collection

8. 打开gzip压缩

中级(这些是你可能在一些相对复杂情况下可能用到的)

9. 重用和延迟加载Views

10. Cache, Cache, 还是Cache!

11. 权衡渲染方法

12. 处理内存警告

13. 重用大开销的对象

14. 使用Sprite Sheets

15. 避免反复处理数据

16. 选择正确的数据格式

17. 正确地设定Background Images

18. 减少使用Web特性

19. 设定Shadow Path

20. 优化你的Table View

21. 选择正确的数据存储选项

进阶级(这些建议只应该在你确信他们可以解决问题和得心应手的情况下采用)

22. 加速启动时间

23. 使用Autorelease Pool

24. 选择是否缓存图片

25. 尽量避免日期格式转换

初学者性能提升

这个部分致力于一些能提高性能的基本策略。

1. 用ARC管理内存

ARC(Automatic Reference Counting, 自动引用计数)和iOS5一起发布,它避免了最常见的也就是经常是由于我们忘记释放内存所造成的内存泄露。它自动为你管理retain和release的过程,所以你就不必去手动干预了。

下面是你会经常用来去创建一个View的代码段:

 UIView *view = [[UIView alloc] init];
 //
 ...
 [self.view addSubview:view];
 [view release];

忘掉代码段结尾的release简直像记得吃饭一样简单。而ARC会自动在底层为你做这些工作。

除了帮你避免内存泄露,ARC还可以帮你提高性能,它能保证释放掉不再需要的对象的内存。这都啥年代了,你应该在你的所有项目里使用ARC!

这里有一些更多关于ARC的学习资源:

Apple’s official documentation

Matthijs Hollemans’s Beginning ARC in iOS Tutorial

Tony Dahbura’s How To Enable ARC in a Cocos2D 2.X Project

If you still aren’t convinced of the benefits of ARC, check out this article on eight myths about ARC to really convince you why you should be using it!

ARC当然不能为你排除所有内存泄露的可能性。由于阻塞, retain 周期, 管理不完善的CoreFoundation object(还有C结构)或者就是代码太烂依然能导致内存泄露。

这里有一篇很棒的介绍ARC不能做到以及我们该怎么做的文章 http://conradstoll.com/blog/2013/1/19/blocks-operations-and-retain-cycles.html。

 

2. 在正确的地方使用 reuseIdentifier

一个开发中常见的错误就是没有给UITableViewCells, UICollectionViewCells,甚至是UITableViewHeaderFooterViews设置正确的reuseIdentifier。

为了性能最优化,tableview用 `tableView:cellForRowAtIndexPath:` 为rows分配cells的时候,它的数据应该重用自UITableViewCell。 一个tableview维持一个队列的数据可重用的UITableViewCell对象。

不使用reuseIdentifier的话,每显示一行table view就不得不设置全新的cell。这对性能的影响可是相当大的,尤其会使app的滚动体验大打折扣。

自iOS6起,除了UICollectionView的cells和补充views,你也应该在header和footer views中使用reuseIdentifiers。

想要使用reuseIdentifiers的话,在一个table view中添加一个新的cell时在data source object中添加这个方法:

static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

这个方法把那些已经存在的cell从队列中排除,或者在必要时使用先前注册的nib或者class创造新的cell。如果没有可重用的cell,你也没有注册一个class或者nib的话,这个方法返回nil。

3.尽量把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!

4. 避免过于庞大的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