Reputation: 7839
I have a simple piece of code that pushes a new view controller onto my navigation controller
- (IBAction)buttonSelected:(id)sender{
caseBillingFormViewController = [[CaseBillingFormViewController alloc] initWithStyle:UITableViewStyleGrouped];
caseBillingFormViewController.returnScreen = @"FALSE";
[self.navigationController pushViewController:caseBillingFormViewController animated:YES];
}
I'm getting a crash on the final line:
[self.navigationController pushViewController:caseBillingFormViewController animated:YES];
I have no idea why this is happening, it's a new addition to iOS6. The code-base has not changed between upgrade versions, so I'm not sure why this is happening.
My caseBillingFormViewController is named within my interface:
CaseBillingFormViewController *caseBillingFormViewController;
I've checked the integrity of the self.navigationController and it all checks out:
NSLog(@"%i",[self.navigationController respondsToSelector:@selector(pushViewController:animated:)]);
//gives 1
The issue is that this only appears on screens governed by a UITableView -
caseBillingFormViewController = [[CaseBillingFormViewController alloc] initWithStyle:UITableViewStyleGrouped];
//crashes
savedOrdersViewController = [[SavedOrdersViewController alloc] initWithNibName:@"SavedOrdersViewController" bundle:[NSBundle mainBundle]];
//does not crash
Can anybody shed some light on why this is happening?
Tested same code on Simulator 5.1 and Simulator 6.0 - error only occurs on the latter.
NB, the error is:
'NSUnknownKeyException', reason: '[<CaseBillingFormViewController 0xc09c0b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key theTableView.'
Upvotes: 0
Views: 768
Reputation: 7839
Okay, due to me assuming it wasn't relevant, I didn't mention that CaseBillingFormViewController
used to have a xib file - when I realised that the xib file wasn't doing much at all, I deleted it and converted the class over to a UITableViewController with all appropriate initialisers.
I'll clarify...
CaseBillingFormViewController.xib
does not exist.
It was deleted, all references removed and the file itself trashed and emptied.
I even went as far as to check the compiled sources and as I'd thought, it wasn't there...
Hence why I assumed it wasn't relevant.
To repair, I had to remove the app from my device and simulator, then clean the build, restart my machine, clean again and then build. As convoluted as it sounds, without even one of those steps, the error remained.
There's a bug in X-Code that doesn't register deleted files especially xibs and storyboards. Here's the response from Apple:
Xcode is not being accurate when assuming which files have been changed, sparking a re-build of the application bundle, especially for storyboards and xib files. As you indicated, you have to do a clean operation for it to realize your changes. This is a bug in Xcode.
If you want to preserve the rest of the sandbox (i.e. the Documents folder, etc.), the Xcode Organizer lets you download the app's standbox (minus the app bundle) from the device to your Mac, where you can in turn upload it back to the device after the app has been changed. So in the Organizer, select the device and its "Applications" item, select the appropriate application, click the Download button, which will download the Data files in that sandbox.
Even though the file was deleted, it was still reading variables from it. The UITableView instance theTableView
in the error, had existed in the xib before it was deleted.
This doesn't mean it's fixed, but it does mean that the solution is out of the hands of anyone in SO. Thanks for your help anyway guys.
Upvotes: 0
Reputation: 41642
Note that 'initWithNibName:bundle:' is the designated initializer for a UIViewController. Does your subclass that with two nils (which is OK)? You have no idea what UIViewController is doing in its init routine, so you must call that or you are on shaky grounds.
If this was working in the past, I assume you implemented 'loadView'. If so, you can create your table there with a style specified as a property, in your subclass init (as long as its calling the designated one to super.)
The reason it worked before and does not now is you got lucky - Apple must be doing something important now in 'initWithNibName:bundle:'.
Also, if you are subclassing UITableViewController (not UIViewController) it may be the case that you need to set self.tableView to self.view - not sure - but in anycase you should verify after you create the object but before you push it that both view and tableView are set - by logging them before the push. If either is nil then don't continue.
Upvotes: 1