性能优化总结2

iOS应用是非常注重用户体验的,不光是要求界面设计合理美观,也要求各种UI的反应灵敏,我相信大家对那种一拖就卡卡卡的 TableView 应用没什么好印象。还记得12306么,那个速度,相信大家都受不了。为了提高 iOS 的运行速度,下面我将抛砖引玉介绍一些我实践过的用来提供iOS程序运行效率的方法,与大家分享,希望能得到更多的反馈和建议。

1,计算代码运行时间:相信数据,不要太相信感觉。不过要注意模拟器和真机的差异。

最简单的工具就是 NSDate,但精度不是太好。

 1 NSDate* tmpStartData = [[NSDate date] retain];
2 //You code here...
3 double deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData];
4 NSLog(@">>>>>>>>>>cost time = %f", deltaTime);
5 或者将运行代码放到如下方法的 block 参数中,然后返回所运行的时间:
6
7 #import <mach/mach_time.h> // for mach_absolute_time() and friends
8
9 CGFloat BNRTimeBlock (void (^block)(void)) {
10 mach_timebase_info_data_t info;
11 if (mach_timebase_info(&info) != KERN_SUCCESS) return -1.0;
12
13 uint64_t start = mach_absolute_time ();
14 block ();
15 uint64_t end = mach_absolute_time ();
16 uint64_t elapsed = end - start;
17
18 uint64_t nanos = elapsed * info.numer / info.denom;
19 return (CGFloat)nanos / NSEC_PER_SEC;
20 }

2,善用性能分析工具。

XCode 自带了很多强大的分析工具,包括静态 Analyze 工具,以及运行时 Profile 工具。

3,关于图片

优先使用[UIImage imageNamed:@""];

与[[UIImage alloc] initWithContentsOfFile:] 和 [UIImage alloc [initWithData:]] 相比,[UIImage imageNamed:]有着更好的效率,这是因为 iOS 会自带 cache 通过 [UIImage imageNamed:] 载入的图像,但该方法有一个缺点,那就是只能载入应用程序 bundle 中的图像,像网络下载的图像就无能无力了。我习惯的做法是自定义一个 ImageCache 类,自己来 cache 图像。

尽量不要使用全屏大小的背景图片;使用 gradient 图片来取代硬编码的 gradient;gradient 图片应当尽可能窄,然后将之拉伸运用到实际场合中去。

4,对于结构复杂的 View,使用 drawRect 自绘而不是从 nib 中载入。

5,对于 TableView,重用 cell;减少 cell 初始化的工作量,延迟装载;定制复杂 cell 时,使用 drawRect 自绘;Cache 尽可能多的东西,包括 cell 高度;尽可能让 cell 不透明;避免使用图像特性,比如 gradients。

6,在线程中使用 autoreleasepool。

7,将一些不太重要的任务放在 idle 时运行。

 1 - (void)idleNotificationMethod {
2 // do something here
3 }
4
5 - (void)registerForIdleNotification
6 {
7 [[NSNotificationCenter defaultCenter] addObserver:self
8 selector:@selector(idleNotificationMethod)
9 name:@"IdleNotification"
10 object:nil];
11 NSNotification *notification = [NSNotification
12 notificationWithName:@"IdleNotification" object:nil];
13 [[NSNotificationQueue defaultQueue] enqueueNotification:notification
14 postingStyle:NSPostWhenIdle];
15 }

8,不要在 viewWillAppear 中做费时的操作。

viewWillAppear: 在 view 显示之前被调用,出于效率考虑,在这个方法中不要处理复杂费时的事情;只应该在这个方法设置 view 的显示属性之类的简单事情,比如背景色,字体等。要不然,用户会明显感觉到 view 显示迟钝。

9,使用多线程来延迟加载资源。比如常见的 TableViewCell 中的网络图像显示,先使用一个默认图像,然后开启线程下载网络图像,当图像下载完成之后,再替换默认图像。

10,关于后台任务

系统进入 background 之后,一般只有10分钟的运行时间,因此有很多值得注意的事项:

  • a) 尽量减少内存的使用。当内存不足时,iOS将kill那些消耗内存最多的 App。
  • b) 释放所有的共享资源,比如 Calendar 与 Address book。当应用程序进入后台时,如果它还在使用或没有释放共享资源,iOS会立即kill掉该应用程序。
  • c) 正确处理App生命周期事件。当进入后台时,应该保持应用程序数据,以便回到前台时能够恢复。当进入 inactive 状态时,应该暂停当前的业务流。iOS运行App在后台运行的时间有限,因此后台代码不应该执行非常耗时的任务,可能的话就使用多线程。当进入后台 时,iOS会保存当前App的一个快照,以便之后在合适的时候(装载view和数据时)呈现给用户以提高用户体验,因此在进入后台时,应该避免在屏幕上呈 现用户信息,以免泄露用户个人资料。
  • d) 不要更新UI或者执行大量消耗CPU或电池的代码。进入后台之后,不应该执行不必要的任务,不要执行 OpenGL ES 调用,应取消 Bonjour 相关的服务,正确处理网络链接失败,避免更新 UI,清除所有的警告或其他弹出对话框。
  • e) 保证后台代码的执行工作正常,注意处理异常。
  • f) 在后台时正确响应系统变化。 如: 设备旋转消息UIDeviceOrientationDidChangeNotification ,重要的时间变化(新的一天开始或时区变化)UIApplicationSignificantTimeChangeNotification ,电池变化UIDeviceBatteryLevelDidChangeNotification 和 UIDeviceBatteryStateDidChangeNotification,用户默认设置变化 NSUserDefaultsDidChangeNotification,本地化语言变化 NSCurrentLocaleDidChangeNotification 等。

11,如果关键代码使用 C/C++/asm 效率更高就使用 C/C++/asm。

12,如果一个方法在一个循环次数非常多的循环中使用,在进入循环前使用 methodForSelector 获取该方法 IMP,然后在循环体中直接使用该 IMP。

13,关于内存释放

在 didReceiveMemoryWarning 中释放内存,比如cache 的图像,view 等,并记得调用 [supper didReceiveMemoryWarning]。清理函数 didReceiveMemoryWarning, viewDidUnload 和 dealloc 都是在方法结尾处调用 supper 的方法。

14,提高 APP 加载速度

避免使用静态初始化,包括静态c++对象,加载时会运行的代码,如+(void) load{} ,会造成在Main函数之前运行额外的代码。

16,利用 cache 空间换时间。cache 是一种常见的空间换时间的提供性能的收到,可以用在相当多的场合。

尽量 cache 那些可重复利用的对象,比如 table cell,date/number formatters,正则表达式,sqlite语句等。

17,关于数据库

缓存经常用到的 sqlite 语句;优化数据库查询语句,用sqlite3_trace和sqlite3_profile来查找性能差的语句;如果可能的话,缓存查询结果缓。

在使用 sqlite_prepare会将SQL查询编译成字节码,要使用bind,重用那些已经prepared的语句。

最新文章

  1. 基于MVC4+EasyUI的Web开发框架形成之旅--MVC控制器的设计
  2. vuejs过滤器
  3. ubuntu cpus 共享打印
  4. HDU 4121 Xiangqi (算是模拟吧)
  5. EffectiveC#8--确保0对于值类型数据是有效的(初始化问题)
  6. Django 分页功能
  7. Tracker-store
  8. Oracle保留小数点后两位的几种方法
  9. 初识 go 语言:方法,接口及并发
  10. 哥们,你真以为你会做这道JVM面试题?
  11. scrapy 让指定的spider执行指定的pipeline
  12. JS在在线人数和访问人数
  13. L0、L1及L2范数
  14. LOJ 6053 简单的函数——min_25筛
  15. java实验三 敏捷开发与XP实践
  16. C# XML序列化和反序列化
  17. Linux:LNMP架构的搭建
  18. Mongodb的性能优化问题
  19. CSS动画详解及transform、transition、translate的区别
  20. 两分钟了解Docker的优势

热门文章

  1. 狗扑论坛 自动刷取VIP狗粮
  2. vs的一些配置
  3. 阿里云安装JDK1.7
  4. step by step 之餐饮管理系统六(数据库访问模块)
  5. Jquery 表单验证
  6. 从csdn博客搬家过来,请多关照!
  7. CCNA第四章第五章Cisco的IOS与SDM及其管理考试要点学习笔记
  8. 深入剖析Nginx一点小笔记
  9. 有用的php函数
  10. 6.用CXF编写基于Spring的WebService