If I run a clean build and a fresh installation, my app installs and runs just fine, however, if I install the previous released version, then overwrite that release with the new version, it will crash on first run.
Steps to Reproduce
- Install and run previous version of my app (1.4) on iPhone 4.
- Close app and kill process.
- Checkout latest version (2.0)
- Delete build directory
- Install and run
- Crash
I'm running Xcode 3.2.5, the 4.2 SDK. My iPhone 4 is 4.2.1.
If you look at the crash logs, it looks like I've got a bad connection in one of my NIBs, but there is no object trying to connect to a 'view' property in my AppController
. Sometimes an identical crash will occur except it will say this class is not key value coding-compliant for the key activityIndicator. This is also wonky, since grep has confirmed that I've got nothing in my project called activityIndicator.
I have three questions:
- Why is my app crashing?
- Does anyone have any ideas on further debugging I can do? I've run out of ideas on how to fix this.
- It's possible (likely?) that when Xcode installs a build on your device that it takes shortcuts that will not be taken when the app is installed from the store. Does anyone know if this is the case and, if so, do you know of a way to simulate the exact app store installation process so I can make sure that I don't kill my app for all the upgraders?
Crash Log
2011-02-10 06:58:32.115 TheApp[132:307] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<AppController 0x14开发者_开发问答d680> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key view.'
*** Call stack at first throw:
(
0 CoreFoundation 0x33ac0987 __exceptionPreprocess + 114
1 libobjc.A.dylib 0x3347b49d objc_exception_throw + 24
2 CoreFoundation 0x33ac0705 -[NSException dealloc] + 0
3 Foundation 0x3367db4f -[NSObject(NSKeyValueCoding) setValue:forUndefinedKey:] + 182
4 Foundation 0x3367d03b _NSSetUsingKeyValueSetter + 90
5 Foundation 0x3367eda3 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 194
6 Foundation 0x33630b17 -[NSObject(NSKeyValueCoding) setValue:forKeyPath:] + 130
7 UIKit 0x3224c60f -[UIRuntimeOutletConnection connect] + 66
8 CoreFoundation 0x33a63fc7 -[NSObject(NSObject) performSelector:] + 18
9 CoreFoundation 0x33a6cd51 -[NSArray makeObjectsPerformSelector:] + 388
10 UIKit 0x3224b577 -[UINib instantiateWithOwner:options:] + 586
11 UIKit 0x3224cb39 -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 92
12 UIKit 0x3209e871 -[UIApplication _loadMainNibFile] + 96
13 UIKit 0x3209a1fd -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 180
14 UIKit 0x3206648b -[UIApplication handleEvent:withNewEvent:] + 1114
15 UIKit 0x32065ec9 -[UIApplication sendEvent:] + 44
16 UIKit 0x32065907 _UIApplicationHandleEvent + 5090
17 GraphicsServices 0x33b0ef03 PurpleEventCallback + 666
18 CoreFoundation 0x33a556ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
19 CoreFoundation 0x33a556c3 __CFRunLoopDoSource1 + 166
20 CoreFoundation 0x33a47f7d __CFRunLoopRun + 520
21 CoreFoundation 0x33a47c87 CFRunLoopRunSpecific + 230
22 CoreFoundation 0x33a47b8f CFRunLoopRunInMode + 58
23 UIKit 0x32099309 -[UIApplication _run] + 380
24 UIKit 0x32096e93 UIApplicationMain + 670
25 TheApp 0x00002781 main + 88
26 TheApp 0x00002724 start + 40
)
--
I should add that the app crashes before it gets to any of my code, i.e. application:didFinishLaunchingWithOptions:
and applicationDidFinishLaunching:
are never called.
I finally figured out what the problem is. The previous version of my app was not localized, so all NIBs were at the top level of the app package. The latest version of my app is localized, so all NIBs are in an en.lproj
directory. When Xcode deploys the app to the device (and the simulator) it does not replace the entire package, it just copies the build files into the existing package. This results in two versions of my NIBs, an outdated version at the top level of my app bundle and the current version inside a subfolder.
When the app is setup it's pulling the topmost NIB, which is the incorrect NIB, which causes a crash. As a result, I will need to actually deploy an .ipa to my phone in order to test the upgrade.
The problem is obviously that the old version leaves some data on the filesystem and the new version can't pick it up properly. If you're saving something like the location of a file, make sure it only stores paths relative to the app's directory, not the whole system paths as the internal bundle ids change during updating.
This has nothing to do with file system locations. You have an inconsistancy with your nib and your application logic. My guess is you've done something like change the type of AppController used in your project without updating your nib or changed one of the IBOutlets without updating your nib. What's happening is during the deserialization of the nib the framework tries to connect something like an IBOutlet that used to exist in the old controller type but no longer exists in the new AppController type.
精彩评论