iOS开发基础73-24种性能优化技巧

在iOS开发中,性能优化是提升用户体验、提高应用响应速度和资源利用率的关键。本文将详细介绍从ARC到View控制在内的一系列优化技巧,帮助开发者在项目升级或开发中避免性能瓶颈。

1. 使用ARC管理内存

自动引用计数(Automatic Reference Counting, ARC)和iOS 5一起发布,它自动为你管理retainrelease的过程,从而避免由于忘记释放内存而导致的内存泄漏。ARC不仅提高了代码的可读性,还减少了手动管理内存的复杂性。ARC通过编译器插入的代码,在对象不再被引用时自动释放内存,提高了应用性能。

2. 在正确的地方使用 reuseIdentifier

在UITableView及UICollectionView中,复用标识符reuseIdentifier极为重要。复用机制避免了频繁创建和销毁视图,从而显著提升性能。

示例代码:

static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

dequeueReusableCellWithIdentifier 方法会重用现有的cell,或在必要时创建新的cell。如果不使用reuseIdentifier,每次显示新行都需要创建一个cell,大大降低滚动性能。

3. 尽量将Views设置为不透明(opaque)

如果view是完全不透明的,将其opaque属性设置为YES,渲染系统会进行优化,从而提高性能。这个属性在Interface Builder或代码中都可以设置。

view.opaque = YES;

在模拟器中可以通过Debug -> Color Blended Layers来查看哪些views没有设置为opaque。

4. 避免过于庞大的XIB

尽管iOS 5 之后Storyboards变得越来越流行,但XIB在某些场景中仍然有用。应尽量减少XIB的体积,将每个View Controller的view层次结构分散到单独的XIB中。加载XIB时,所有内容都会被放入内存,包括不立即使用的资源,造成内存浪费。

5. 不要阻塞主线程

主线程用于UI渲染和事件处理,阻塞主线程会导致应用无响应。在进行任何耗时操作时,应使用后台线程或异步处理方法。

示例代码:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 执行耗时操作
    dispatch_async(dispatch_get_main_queue(), ^{
        // 更新UI
    });
});

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

确保图片大小与UIImageView的尺寸匹配,避免运行时缩放造成的性能损耗。如果图片来自远程服务,可以在下载完成后进行一次性缩放。

UIGraphicsBeginImageContext(view.frame.size);
[image drawInRect:view.bounds];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

7. 选择正确的Collection

不同数据集合(Collection)在不同场景有不同的性能表现:

  • NSArray:有序,索引查找快,值查找慢。
  • NSDictionary:键值对,键查找快。
  • NSSet:无序,值查找快,插入和删除快。

8. 打开gzip压缩

开启gzip压缩可以大大减小从服务器下载的数据量,提高传输效率。iOS的NSURLConnection默认支持gzip压缩。

9. 重用和延迟加载(lazy load)Views

避免一次性创建所有subview,应在需要时才创建,从而节省内存。例如,UITableView和UICollectionView会在需要时才创建cell,使得内存利用率更高。

10. 缓存策略

对无频繁变化但需多次读取的资源进行缓存,例如远程服务器的响应、图片或计算结果。使用NSCache可以在内存不足时自动清理缓存。

11. 权衡渲染方法

在iOS中,有多种方法渲染复杂UI。优先使用预渲染的图片而非代码绘制,可以减少CPU和内存使用,但需要权衡应用体积的增加。

12. 处理内存警告

系统在内存不足时会发出警告,应用需要响应这些警告释放不必要的内存资源。覆盖UIViewController的didReceiveMemoryWarning方法,移除不可见view及缓存数据。

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // 移除缓存数据
}

13. 重用大开销对象

对于一些创建开销大的对象,如NSDateFormatterNSCalendar,应尽量重用。

@property (nonatomic, strong) NSDateFormatter *dateFormatter;

- (NSDateFormatter *)dateFormatter {
    if (!_dateFormatter) {
        _dateFormatter = [[NSDateFormatter alloc] init];
        _dateFormatter.dateFormat = @"yyyy-MM-dd";
    }
    return _dateFormatter;
}

14. 使用Sprite Sheets

Sprite sheet通过将多个图像合并成一张大图,使用一个纹理来渲染多张图片,大大提高渲染性能和内存使用效率。

15. 避免反复处理数据

在读取远程数据时,尽量使用适合展示的数据结构,避免在客户端进行多次转换,提高效率。

16. 选择正确的数据格式

解析JSON通常比XML更快,且JSON数据通常更小,传输效率更高。iOS 5之后的内置JSON解析器进一步提高了处理效率。不过,XML适用于处理大批量数据和流媒体。

17. 正确设定背景图片

通过UIImageView设置大背景图,或通过UIColorcolorWithPatternImage方法设置小的平铺背景图,节省内存,提高渲染速度。

18. 减少使用Web特性

UIWebView 远没有 Safari迅速,尽量减少JavaScript使用并异步加载。确保图像大小合适,避免过大的图像文件。

19. 设定Shadow Path

为视图的阴影设置shadowPath,避免每次渲染时重新计算,提高性能。

view.layer.shadowPath = [UIBezierPath bezierPathWithRect:view.bounds].CGPath;

20. 优化Table View

确保流畅的TableView滚动,正确使用reuseIdentifier、设置view的opaque属性、避免图片缩放,使用异步加载,减少subviews数量。

21. 选择合适的数据存储选项

选择合适的数据存储方式:NSUserDefaults适用小数据,SQL和Core Data适用于复杂数据结构和频繁查询的场景。使用FMDB库简化SQLite操作。

22. 使用Autorelease Pool

在创建大量临时对象时,手动创建autorelease pool,防止内存持续增长。

@autoreleasepool {
    // 创建大量临时对象
}

23. 选择是否缓存图片

需要反复使用的图片应使用imageNamed方法加载并缓存。如果图片用于一次性展示,应使用imageWithContentsOfFile方法避免浪费内存。

24. 避免日期格式转换

优先使用Unix时间戳,避免频繁使用NSDateFormatter。如果必须使用NSDateFormatter,确保重用实例。

posted @ 2015-10-29 21:24  Mr.陳  阅读(2104)  评论(0编辑  收藏  举报