开发者

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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜