iOS性能优化的25条建议

    iOS性能优化的25条建议
                  入门级
1.用ARC管理内存

2.在正确的地方使用reuseIdentifier(cell默认标识符)

3. 尽可能使Views不透明(提升渲染速度)
   设置Views的opaque属性为YES(默认)。

4. 避免庞大的XIB
   使XIB尽量简单。尝试为每个Controller配置一个单独的XIB,尽可能把一个View Controller的view层次结构分散到单独的XIB中去。

5.不要block主线程
   永远不要使主线程承担过多。因为UIKit在主线程上做所有工作,渲染,管理触摸反应,回应输入等都需要在它上面完成。大部分阻碍主进程的情形是你的app在做一些牵涉到读写外部资源的I/O操作,比如存储或者网络

6.在Image Views中调整图片大小
   如果要在`UIImageView`中显示一个来自bundle的图片,你应保证图片的大小和UIImageView的大小相同。如果图片是远端服务加载的,你可以在下载完成后,最好是用background thread,缩放一次,然后在UIImageView中使用缩放后的图片。
[self performSelectorInBackground:@selector(disposedealImage:) withObject:docids];

7.选择正确的Collection
    选择对业务场景最合适的类或者对象,如:
Arrays: 有序的一组值。 使用index来查找很快,使用value查找很慢, 插入/删除很慢。
Dictionaries: 存储键值对。 用键来查找比较快。
Sets: 无序的一组值。 用值来查找很快,插入/删除很快

8.打开gzip压缩(减小文档大小)


                      中级

9.重用和延迟加载Views
   模仿`UITableView`和`UICollectionView`的操作: 不要一次创建所有的subview,而是当需要时才创建,当它们完成了使命,把他们放进一个可重用的队列中。这样的话你就只需要在滚动发生时创建你的views,避免了不划算的内存分配。

10.Cache, Cache, 还是Cache!
    缓存所需要的,也就是那些不大可能改变但是需要经常读取的东西。远端服务器的响应,图片,甚至计算结果,比如UITableView的行高。

11.权衡渲染方法
用事先渲染好的图片更快一些,因为如此一来,iOS就免去了创建一个图片再画东西上去,然后显示在屏幕上的程序。问题是你需要把所有你需要用到的图片放到app的bundle里面,这样就增加了体积。 这就是使用可变大小的图片更好的地方了: 你可以省去一些不必要的空间,也不需要再为不同的元素(比如按钮)来做不同的图。总得来说,你需要权衡一下利弊,到底是要性能能还是要bundle保持合适的大小。

12.处理内存警告
    如果你的app收到了内存警告,它就需要尽可能释放更多的内存。最佳方式是移除对缓存、图片、object和其他一些可以重创建的objects的strong references。幸运的是,UIKit提供了几种收集低内存警告的方法:
     在app delegate中使用`applicationDidReceiveMemoryWarning:` 的方法
     在你的自定义UIViewController的子类(subclass)中覆盖`didReceiveMemoryWarning`
     注册并接收 UIApplicationDidReceiveMemoryWarningNotification 的通知
一旦收到这类通知,你就需要释放任何不必要的内存使用。
    例如,UIViewController的默认行为是移除一些不可见的view, 它的一些子类则可以补充这个方法,删掉一些额外的数据结构。一个有图片缓存的app可以移除不在屏幕上显示的图片。

13.重用大开销的对象

    下面的代码说明了使用一个属性来延迟加载(懒加载)一个date formatter. 第一次调用时它会创建一个新的实例,以后的调用则将返回已经创建的实例:

// in your .h or inside a class extension
@property (nonatomic, strong) NSDateFormatter *formatter;
 
// inside the implementation (.m)
// When you need, just use self.formatter

- (NSDateFormatter *)formatter {
    if (! _formatter) {
        _formatter = [[NSDateFormatter alloc] init];
        _formatter.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy"; // twitter date format
    }
    return _formatter;
}


14. 使用Sprite Sheets(游戏开发)
15. 避免反复处理数据
    在服务器端和客户端使用相同的数据结构。
16.选择正确的数据格式
    解析JSON会比XML更快一些,JSON也通常更小更便于传输。但是XML也有XML的好处,比如使用SAX来解析XML就像解析本地文件一样,你不需像解析json一样等到整个文档下载完成才开始解析。当你处理很大的数据的时候就会极大地减低内存消耗和增加性能。

17.正确地设定Background Images
    如果你使用全画幅的背景图,就使用UIImageView,因为UIColor的colorWithPatternImage是用小图平铺来创建背景的。

18.减少使用Web特性
    尽可能移除不必要的javascript,避免使用过大的框架。能只用原生js就更好了。另外,尽可能异步加载javascript。保证图片符合你使用的大小,使用Sprite sheet提高加载速度和节约内存。
19.设定Shadow Path(关于视图)

20. 优化你的Table View

正确使用`reuseIdentifier`来重用cells
尽量使所有的view opaque,包括cell自身
避免渐变,图片缩放,后台选人
缓存行高
如果cell内实现的内容来自web,使用异步加载,缓存请求结果
使用`shadowPath`来画阴影
减少subviews的数量
尽量不使用`cellForRowAtIndexPath:`,如果你需要用到它,只用一次然后缓存结果
使用正确的数据结构来存储数据
使用`rowHeight`, `sectionFooterHeight` 和 `sectionHeaderHeight`来设定固定的高,不要请求delegate

21.选择正确的数据存储选项
使用`NSUerDefaults`
使用XML, JSON, 或者 plist
使用NSCoding存档
使用类似SQLite的本地SQL数据库
使用 Core Data

NSUserDefaults:虽然它很nice也很便捷,但是它只适用于小数据,比如一些简单的布尔型的设置选项,再大点你就要考虑其它方式了
XML:总体来说,你需要读取整个文件到内存里去解析,这样是很不经济的。使用SAX又是一个很麻烦的事情。
NSCoding:不幸的是,它也需要读写文件,所以也有以上问题。

    在这种应用场景下,使用SQLite 或者 Core Data比较好。使用这些技术你用特定的查询语句就能只加载你需要的对象。
    在性能层面来讲,SQLite和Core Data是很相似的。他们的不同在于具体使用方法。Core Data代表一个对象的graph model,但SQLite就是一个DBMS。Apple在一般情况下建议使用Core Data,但是如果你有理由不使用它,那么就去使用更加底层的SQLite吧


                      进阶级
22.加速启动时间
使它尽可能做更多的异步任务,比如加载远端或者数据库数据,解析数据。避免过于庞大的XIB,因为他们是在主线程上加载的。尽量使用Storyboards!
注意,用Xcode debug时watchdog并不运行,一定要把设备从Xcode断开来测试启动速度

23.使用Autorelease Pool
    NSAutoreleasePool`负责释放block中的autoreleased objects。一般情况下它会自动被UIKit调用。但是有些状况下你也需要手动去创建它。

24.选择是否缓存图片
    imageNamed的优点是当加载时会缓存图片。相反的,imageWithContentsOfFile仅加载图片。如果你要加载一个大图片而且是一次性使用,那么就没必要缓存这个图片,用`imageWithContentsOfFile`足矣,这样不会浪费内存来缓存它。 然而,在图片反复重用的情况下`imageNamed`是一个好得多的选择。

25.尽量避免日期格式转换
如果你可以控制你所处理的日期格式,尽量选择Unix时间戳。你可以方便地从时间戳转换到NSDate:
- (NSDate*)dateFromUnixTimestamp:(NSTimeInterval)timestamp {
 return [NSDate dateWithTimeIntervalSince1970:timestamp];
 }
需要注意的是,许多web API会以微秒的形式返回时间戳,因为这种格式在javascript中更方便使用。记住用`dateFromUnixTimestamp`之前除以1000就好了。

博客地址:http://blog.jobbole.com/37984/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值