在iPhone上启动缓慢

时间:2010-01-07 05:24:01

标签: iphone performance

我正在调试iPhone应用程序的慢速启动(Xcode,Objective C ++)。这是一个基于tabbar的应用程序,有三个选项卡。所有三个选项卡都加载到一个NIB中 - 总共约20个对象。

第一轮重要初始化发生在第一个选项卡视图控制器的viewDidLoad处理程序中。但是,main()和该方法的开始时间之间大约需要1秒 - 约占总加载时间的2/3。问题 - 在那段时间发生了什么,我该如何调查(没有单步执行反汇编)?据我所知,在这两个时刻之间没有我的代码 - 延迟完全发生在系统代码中。

也许某种仪器可以给我每个功能的时间档案?

捆绑包总共大约4 MB,但是我在applicationDidFinishLaunching处理程序中加载了最大的文件(~3.5 MB)。从捆绑中删除该文件并注释掉相关代码对于1秒的延迟没有任何作用。

更新:毕竟有调试干扰。如果我在观看控制台的同时在设备上运行它,我们的启动时间要短得多,延迟的比例 - 系统代码与我的代码一样 - 也是不正确的。但是,在main和viewDidLoad之间存在明显的延迟,并且它占总加载时间的50%左右。

顺便说一下,在将一个较大的文件从bundle中完全加载到内存中的所有方法中,最快的是直接内存映射(使用POSIX mmap())。

4 个答案:

答案 0 :(得分:4)

如果您真的对启动期间执行的内容以及每个方法运行的相对时间感到好奇,可以创建自定义DTrace脚本来跟踪此情况。我在this article结束时描述了如何做到这一点。此脚本将显示应用程序执行的每个方法,从启动到-applicationDidFinishLaunching:结束,以及在该方法中花费的时间。您可以将此脚本作为Instruments中的自定义工具运行,也可以作为独立脚本运行(独立脚本在加载的系统上更加准确)。

这种方法的主要警告是它只能在模拟器中运行,因为目前iPhone OS本身缺乏对DTrace的支持。但是,您应该能够提取应用程序启动时执行事务的顺序,以及应用程序在每种方法中花费的相对时间。这甚至会显示在您的应用程序启动时进行的幕后私有API调用,这可能会提供一些有关正在发生的事情的其他线索。

对于其他启动调整建议,我建议阅读James Thomson的文章"How To Make Your iPhone App Launch Faster"

答案 1 :(得分:3)

这里有两件事可以发生。如果您正在从XCode中调试您的应用程序,那么应用程序很有可能在启动时等待连接到GDB调试器。根据我的经验,这需要大约一秒钟。尝试运行您的应用程序,而不是在XCode中说“Build and Go”,看看结果是否有所不同。 (只需在主屏幕上单击它)

您的NIB文件也可能是问题所在。 20个对象不是太多,但是如果其他所有选项都失败,您可以考虑将每个选项卡分成单独的NIB文件。从主NIB文件引用的NIB文件的内容是延迟加载的,因此应用程序不会加载两个选项卡的视图,这两个选项卡在被选中之前是不可见的。这可能会让您在启动时获得性能提升,但我认为它不会占用一整秒。

Apple在iPhone SDK中有一些出色的性能分析工具,但它们很难找到。在“运行”菜单中,选择“使用Performance Tool运行” - > “CPU采样器。”这将启动一个名为Instruments的独立应用程序,它允许您进行各种强大的运行时分析。选择CPU仪器后,“仪器”窗口的下半部分将显示应用程序中CPU时间的详细信息。您可以双击功能以深入了解它们,并获得所用循环百分比的逐行分解。它应该为您提供有关具体导致问题的更多信息。

答案 2 :(得分:0)

如果您发现xib文件太大,我建议您使用纯代码构建UI。 大的xib文件肯定会减慢你的启动时间,并且当你第一次在你的xib中使用一个对象时也会减慢你的应用程序。

我不在我的项目中使用xib,因为当有人在svn中更改了xib时,你几乎找不到改变的内容。也就是说,xib与SVN的关系并不顺利。

答案 3 :(得分:0)

我建议将你的应用分成三个NIBS;标签栏和标签栏控制器在第一次启动时显示,然后在用户第一次切换到它们时懒惰地加载另外两个。

我相信您可以使用文件>>在Interface Builder中分解接口功能以实现此目的。