6

在帖子Using initWithNibName 没有任何改变,他展示了相同 View Nib 定义的两种用法,在第一种情况下,他只是调用 alloc/init,第二种情况下,他指定了 initWithNibName。

所以,虽然这总是有效的:

MyViewController *vctrlr = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; [self.navigationController pushViewController:vctrlr animated:YES]; [vctrlr release];

以下适用于我继承的所有视图控制器,但不适用于我的!

TheirViewController *vctrlr = [[TheirViewController alloc] init]; [self.navigationController pushViewController:vctrlr animated:YES]; [vctrlr release];

iOS 编程新手,我继承了一些代码。所有视图控制器的视图都在 IB 中定义,但是这些视图控制器的分配/初始化创建不一致。我创建了一个新的视图控制器和 XIB,但除非我使用 initWithNibName,否则它不起作用(当我将视图控制器推到导航控制器上时它会崩溃)。我无法说出我的视图控制器与其他控制器有何不同......有什么提示吗?除了我的之外,我能够删除应用程序中所有其他视图控制器的 initNibName 用法。

4

2 回答 2

1

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;
}
于 2013-09-27T23:36:56.153 回答
0
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;
}
于 2016-06-08T09:43:18.640 回答