We are receiving a crash log from iTunes connect that is a little strange.
We were preivously having problems with our app taking to long to return from ApplicationDidFinishLaunching. This was caused by doing a too much work inside of applicationDidFinishLaunching and we exceeded the 20 second time out on slower devices.
To fix this we moved all of our setup code out of ApplicationDidFinishLaunching and moved it into a special secondaryLoadingController. On top of that we moved the setup code inside of that controller to a separate thread.
However, we are still seeing crash logs that开发者_如何学C say our app failed to launch in time even though the crash log shows a call to [UIApplication _reportAppLaunchFinished]
. To me, this indicates that the app has finished launching and we should be free to take as long as we want to run our setup code. Below is the crash log.
Thanks for any help you can offer.
Incident Identifier: 429360D5-6B02-49BE-9A0F-164DC521BE36
Hardware Model: iPod2,1
Process: XYZ [357]
Path: /var/mobile/Applications/D5038F26-CC5B-48E5-824E-090163B5C0C4/XYZ.app/XYZ
Identifier: XYZ
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2010-09-28 13:35:25.138 -0700
OS Version: iPhone OS 4.0 (8A293)
Report Version: 104
Exception Type: 00000020
Exception Codes: 0x8badf00d
Highlighted Thread: 0
Application Specific Information:
com.xyz.xyz failed to launch in time
elapsed total CPU time (seconds): 20.180 (user 15.910, system 4.270), 100% CPU
elapsed application CPU time (seconds): 10.960, 54% CPU
Thread 0:
0 libobjc.A.dylib 0x3523a50c objc_msgSend + 44
1 CoreFoundation 0x363bf568 -[__NSArrayM addObject:]
2 XYZ 0x0000a152 -[Database fetchDrinks:] + 290
3 XYZ 0x0000677c -[Database getAllDrinks] + 136
4 XYZ 0x0003a164 -[SecondaryLoadingViewController viewDidLoad] + 208
5 UIKit 0x323e582c -[UIViewController view]
6 UIKit 0x323f9628 -[UIViewController viewControllerForRotation]
7 UIKit 0x323f9574 -[UIViewController _visibleView]
8 UIKit 0x323f94fc -[UIViewController rotatingContentViewForWindow:]
9 UIKit 0x3249a514 -[UIClientRotationContext initWithClient:toOrientation:duration:andWindow:]
10 UIKit 0x32499314 -[UIWindow _setRotatableClient:toOrientation:duration:force:]
11 UIKit 0x32497d78 -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:]
12 UIKit 0x32497534 -[UIViewController presentModalViewController:withTransition:]
13 UIKit 0x324977fc -[UIViewController _tryRecursivelyPresentModalViewController:withTransition:]
14 UIKit 0x324977c0 -[UIViewController _tryRecursivelyPresentModalViewController:withTransition:]
15 UIKit 0x32496e00 -[UIViewController presentModalViewController:withTransition:]
16 UIKit 0x3249699c -[UIViewController presentModalViewController:animated:]
17 XYZ 0x000044a2 -[HomeViewController viewDidLoad] + 82
18 UIKit 0x323e582c -[UIViewController view]
19 UIKit 0x323fd68c -[UIViewController contentScrollView]
20 UIKit 0x323fd4ac -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:]
21 UIKit 0x323fd358 -[UINavigationController _layoutViewController:]
22 UIKit 0x323fccb8 -[UINavigationController _startTransition:fromViewController:toViewController:]
23 UIKit 0x323fca1c -[UINavigationController _startDeferredTransitionIfNeeded]
24 UIKit 0x323fc90c -[UINavigationController viewWillLayoutSubviews]
25 UIKit 0x323fc43c -[UILayoutContainerView layoutSubviews]
26 UIKit 0x32370ab0 -[UIView(CALayerDelegate) _layoutSublayersOfLayer:]
27 CoreFoundation 0x363c85ba -[NSObject(NSObject) performSelector:withObject:]
28 QuartzCore 0x30c8c61c 0x30c82000 + 42524
29 QuartzCore 0x30c8c2a4 0x30c82000 + 41636
30 QuartzCore 0x30c8bbb0 0x30c82000 + 39856
31 QuartzCore 0x30c8b7d8 0x30c82000 + 38872
32 QuartzCore 0x30c8b684 0x30c82000 + 38532
33 UIKit 0x323d99d4 -[UIApplication _reportAppLaunchFinished]
34 UIKit 0x3251d77c -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:]
35 UIKit 0x323d87b8 -[UIApplication handleEvent:withNewEvent:]
36 UIKit 0x323d7eb4 -[UIApplication sendEvent:]
37 UIKit 0x323d77e8 _UIApplicationHandleEvent
38 GraphicsServices 0x33c4dedc PurpleEventCallback
39 CoreFoundation 0x364142ac __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__
40 CoreFoundation 0x364161d6 __CFRunLoopDoSource1
41 CoreFoundation 0x3641718e __CFRunLoopRun
42 CoreFoundation 0x363be0bc CFRunLoopRunSpecific
43 CoreFoundation 0x363bdfca CFRunLoopRunInMode
44 UIKit 0x32363b18 -[UIApplication _run]
45 UIKit 0x32361fb8 UIApplicationMain
46 XYZ 0x00002b20 main + 36
47 XYZ 0x00002af0 start + 32
UPDATE I am attempting to run the time consuming import code (only happens on an application update) on a separate thread. I am even updating the GUI using an AlertView with an embedded progress bar so the user knows something is still happening. During our testing process this works fine. Below is the thread code that seems to not be working. The crash log seems to indicate that all work is being done on the main thread.
if ([database appDidUpdate] == YES) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
dbImportThread = [[NSThread alloc] initWithTarget:self selector:@selector(import) object:nil];
[dbImportThread start];
[pool release];
- (void)import {
//do importing work and update the gui with the progress
}
You are still blocking the main thread too long - be it during launch or later. Only do lightweight GUI work on the main thread. The main thread is also blocked if you perform work on a second thread but wait in your main thread for the results.
Instruments is your friend here.
seems everything is performing on the main thread... (am I right?) If this is the case it may stuck your UI. Did you consider to load your database information on another thread and update your GUI as you get the data? second, you can measure the performance of each chunk of code in time-cosuming relation and see what exactly takes it so much time to load.
its setting off a watchdog timer. its blocking the main thread for more than 20 seconds. as has been said, you need to lazy load. only load up something that will be visible on the first screen.
run some time profiles on it using instruments, try and fix anything that is particularly inefficient and try to kick as much as you can get away with onto a background thread.(IE anything that is not going to be updating the UI) you can load lots of data on a background thread, and once the data objects have been set up pass them back to the main thread, and run an update selector from there.
Although I don't have direct experience with this, after reading your crash log, it appears that the device noticed your app taking 100% CPU time for slightly longer than 20 seconds after launch. It would appear that even though this CPU usage isn't inside the applicationDidFinishLaunching:
method, the operating system isn't fooled and terminates your app.
精彩评论