When do I need to call -[UIViewController initWithNibName:bundle:]?
In post Using initWithNibName changes absolutely nothing, he shows two uses of the same View Nib definition, in the first case, he simply calls alloc/init and the second, he specifies initWithNibName.
So, while this always works:
MyViewController *vctrlr = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
[self.navigationController pushViewController:vctrlr animated:YES];
[vctrlr release];
The following works for all the View Controllers I've inherited, but not mine!
TheirViewController *vctrlr = [[Thei开发者_如何学PythonrViewController alloc] init];
[self.navigationController pushViewController:vctrlr animated:YES];
[vctrlr release];
New to iOS programming, I inherited some code. All the View Controllers' views are defined in IB, but there was inconsistent allocation/init creation of those view controllers. I created a new View Controller and XIB, but it does not work unless I use initWithNibName (it crashes when I push the view controller onto the Nav Controller). I cannot tell how my view controller is different than the others... any hints? I was able to delete the initNibName usage for all the other view controllers in the app except mine.
You can pass any string name to initWithNibName:
. You are not just restricted to calling initWithNibName:@"MyClassName"
when your class is called MyClassName
. It could be initWithNibName:@"MyClassNameAlternateLayout"
.
This becomes useful if you need to load a different nib depending on what the app needs to do. While I try to have one nib per view controller per device category (iPhone or iPad) whenever possible to make development and maintenance simpler, I could understand if a developer would want to provide a different layout or different functionality at times.
Another important point is that initWithNibName:bundle: is the designated initializer for UIViewController
. When you call -[[UIViewController alloc] init]
, then initWithNibName:bundle:
is called behind the scenes. You can verify this with a symbolic breakpoint. In other words, if you simply want the default behavior, it is expected that you can call -[[UIViewController alloc] init]
and the designated initializer will be called implicitly.
If, however, you are calling -[[UIViewController alloc] init]
and not getting the expected behavior, it's likely that your UIViewController subclass has implemented - (id)init
incorrectly. The implementation should look like one of these two examples:
- (id)init
{
self = [super init];
if (self) {
// custom initialization
}
return self;
}
or
- (id)init
{
NSString *aNibName = @"WhateverYouWant";
NSBundle *aBundle = [NSBundle mainBundle]; // or whatever bundle you want
self = [self initWithNibName:aNibName bundle:aBundle];
if (self) {
// custom initialization
}
return self;
}
If you want to work following code:
MyViewController *vctrlr = [[MyViewController alloc] inil];
[self.navigationController pushViewController:vctrlr animated:YES];
Then you should implement following both methods in MyViewController:
- (id)init
{
self = [super initWithNibName:@"MyViewController" bundle:nil];
if (self != nil)
{
// Do initialization if needed
}
return self;
}
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle
{
NSAssert(NO, @"Init with nib");
return nil;
}
精彩评论