2010-01-07 50 views
4

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

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

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

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

更新:毕竟有调试干扰。如果我在观看控制台的同时在设备上运行它,启动时间会大大缩短,延迟系统代码占我代码的比例也会出现偏差。但是,main和viewDidLoad之间存在明显的延迟,约占总加载时间的50%。

顺便说一句,从捆绑包中加载大文件到内存的所有方法中,最快的是直接内存映射(使用POSIX mmap())。

回答

4

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

您的NIB文件也可能是问题。 20个对象不是太多,但是如果其他所有内容都失败,您可能会考虑将每个制表符分为单独的NIB文件。从主要NIB文件引用的NIB文件的内容被延迟加载,因此应用程序将不会加载两个选项卡的视图,直到它们被选中为止。这可能会给你在启动时提升性能,但我认为它不会占用一秒钟的时间。

苹果在iPhone SDK中有一些很棒的性能分析工具,但是它们有点难找。在运行菜单中,选择“使用性能工具运行” - >“CPU采样器”。这将启动一个名为Instruments的单独应用程序,它允许您执行各种优秀的运行时分析。选择CPU时,仪器窗口的下半部分提供了应用中CPU时间的细节。您可以双击函数以潜入它们中,并逐行分解所用循环的百分比。它应该给你更多关于具体是什么导致你的问题的信息。

+0

我正在计算程序内的时间,所以调试器的干扰应该是最小的。在main()得到控制的时候,调试器应该已经被连接了。 我知道他们建议为制表符分开NIB,但我尝试从第二个和第三个选项卡中删除所有内容 - 延迟几乎相同。 我运行了CPU监视器。有点难以解释。 :(它说72%的时间花在mach_msg_trap下 - 但不是系统的通用“等待事件”功能吗? – 2010-01-07 05:56:45

+0

实际上,我发现调试器确实会造成显着的干扰,特别是在启动时间时。建议将您的代码记录到控制台的时间,在设备上手动启动应用程序,并从管理器中的设备中读取控制台日志中的时间。 – 2010-01-07 16:28:19

+0

我已经使用NSLog()记录时间。是否会出现在管理器中? – 2010-01-07 20:27:04

0

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

我没有在我的项目中使用xib,因为当有人在svn中更改xib时,很难找到发生了什么变化。也就是说,xib对于SVN并不好。

0

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

我相信你可以使用界面生成器中的文件>>分解接口功能来实现这一点。

+0

这是官方线路。但请参阅本的回答下的评论。 – 2010-01-07 14:26:38

4

如果您确实对启动过程中执行的内容感到好奇,以及每个方法运行的相对时间,您可以创建一个自定义DTrace脚本来跟踪它。我描述了如何在this article结束时做到这一点。该脚本将向您显示您的应用程序按启动顺序执行的每个方法以及在该方法中花费的时间,以及-applicationDidFinishLaunching:的结尾。您可以在乐器中将其作为自定义乐器运行,也可以作为独立脚本运行(独立脚本在负载下的系统上更加准确)。

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

对于额外的启动调整建议,我建议阅读詹姆斯汤姆森的文章"How To Make Your iPhone App Launch Faster"