The final update . It turns out that fixing this problem is depressing. Go to the .xcodeproj directory inside your project and delete the <username>.mode1v3 and <username>.pbxuser . This fixed it. Boo, Xcode.
I will start by saying this is not your usual save / release error. This has just begun to happen in the development branch of my code, the error is missing from the main branch, and I am having problems finding any differences in the source indicating the answer. So I just get to the gory stuff.
I have a view controller class. It has several properties that reference a couple of other controllers. Each of them is loaded through the getter receiver as needed, for example:
- (NotesViewController *)notesViewController { if (notesViewController == nil) { notesViewController = [[NotesViewController alloc] initWithNibName:@"NotesViewController" bundle:nil]; } return notesViewController; }
When you later call [self notesViewController] , all this is good. This one, however, just stops working:
- (DateFieldController *)dateFieldController { NSLog(@"made it into the method at least ..."); if (dateFieldController == nil) { NSLog(@"nib loader, don't let us down..."); dateFieldController = [[DateFieldController alloc] initWithNibName:@"DateFieldController" bundle:nil]; } return dateFieldController; }
When this method is called in the same way as other accessors, it explodes, apparently, during the loading of the knife, but, possibly, before it:
2010-07-08 11:44:58.029 MyApp[24404:207] made it into the method at least ... 2010-07-08 11:44:58.030 MyApp[24404:207] nib loader, don't let us down... Program received signal: "EXC_BAD_ACCESS". (gdb) bt
Something unpleasant seems to be happening in the Simulator SDK when starting the knife loading method. In fact, perhaps earlier. Overloading the thread loading initializer with a small NSLog action in the DateFieldController , we suspiciously see nowhere:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { NSLog(@"come on, you..."); if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) { NSLog(@"rock on!"); } return self; }
Suffice it to say that none of these NSLog instructions are executed.
So what is going on? Why does it annoy me at runtime? (Switching the call from self.dateFieldController to [self dateFieldController] does not fix the error - and remember that this code is exactly the same as on my main branch, where it does not fail).
FWIW, I create a 64-bit version of Xcode 3.2.3, compile for Simulator 4.0, Debug, i386 arch (in the new version of Mac Book Pro running OS X 10.6.3), for the purpose of deployment, the project settings are set to "iPhone OS 3.0 "(up this 3.1.3 also cannot be fixed).
Update: as requested, implementation of controllerForFieldType: ::
- (id)controllerForFieldType:(Type *)type { id controller = nil; if ([type.mode isEqualToString:@"note"]) { controller = self.notesViewController; } else if ([type.mode isEqualToString:@"date"]) { NSLog(@"going for it, attempting to load dateFieldController from accessor..."); controller = self.dateFieldController; } else { controller = self.fieldViewController; } return controller; }
I left this before because I donβt think it is particularly relevant, the problem seems to occur later on the stack, in the actual getter method of DateFieldController .
Update II: in @zneak suggesting, I turned on the Run β Enable Guard Malloc option and looked at the script again. The results are basically the same, but the internal backtrace at runtime is different. It would seem that something is wrong with the class or NIB, which prevents its decryption:
2010-07-08 12:26:26.180 Strip[24961:207] made it into the method at least ... 2010-07-08 12:26:26.289 Strip[24961:207] nib loader, don't let us down... Program received signal: "EXC_BAD_ACCESS". Data Formatters temporarily unavailable, will re-try after a 'continue'. (Not safe to call dlopen at this time.) (gdb) bt #0 0x028cd41f in attachMethodLists () #1 0x028cdf77 in realizeClass () #2 0x028cedad in _class_getNonMetaClass () #3 0x028c8eb0 in _class_initialize () #4 0x028ce1f6 in prepareForMethodLookup () #5 0x028c76c9 in lookUpMethod () #6 0x028c7836 in _class_lookupMethodAndLoadCache () #7 0x028d5ad3 in objc_msgSend () #8 0x00007b81 in -[EntryViewController controllerForFieldType:] (self=0x38cfaf30, _cmd=0x190c8f, type=0x3cacbfe0) at /Users/wgray/Documents/Sources/iPhone/strip-iphone/Classes/EntryViewController.m:482 ...snip... #22 0x00001de4 in main (argc=1, argv=0xbfffefec) at /Users/wgray/Documents/Sources/iPhone/strip-iphone/main.m:14 (gdb)
Update III: in which the plot thickens. In the @ohorob comment in the comments, I added env arg OBJC_PRINT_INITIALIZE_METHODS = YES and found that each initialization of each class in the application looks good, except for the one discussed here. Each of them looks like this on the console output:
objc[26750]: INITIALIZE: calling +[UIPinchGestureRecognizer initialize] objc[26750]: INITIALIZE: finished +[UIPinchGestureRecognizer initialize] objc[26750]: INITIALIZE: UIPinchGestureRecognizer is fully +initialized
When I launch the application and select the row of the table that causes the explosion, we just see the output of the nslog console before the failure and the failure itself. I would like to think that this means that we could rule out incorrect initialization, but I lack an expert at runtime.
I did a thorough audit of the code differences between the main branch and the dev branch and did not find anything that indicated that I had already stepped on the pointer, but I continue to think that, most likely, I think this is happening.