我啥时候需要调用 -[UIViewController initWithNibName:bundle:]?

Posted

技术标签:

【中文标题】我啥时候需要调用 -[UIViewController initWithNibName:bundle:]?【英文标题】:When do I need to call -[UIViewController initWithNibName:bundle:]?我什么时候需要调用 -[UIViewController initWithNibName:bundle:]? 【发布时间】:2011-05-26 01:06:48 【问题描述】:

在Using initWithNibName changes absolutely nothing 帖子中,他展示了同一个 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 用法。

【问题讨论】:

通常最好指定NIB名称,因为它实际上是从视图控制器中抽象出视图。例如,如果您有一个控制器,其视图根据某些条件略有不同,您可以将单独的 nib 作为视图加载。 你在vctrlr中实现了loadView方法吗? loadViews 在这两种情况下都没有实现。 【参考方案1】:

您可以将任何字符串名称传递给initWithNibName:。当您的班级被称为MyClassName 时,您不仅限于呼叫initWithNibName:@"MyClassName"。可能是initWithNibName:@"MyClassNameAlternateLayout"

如果您需要根据应用需要执行的操作来加载不同的 nib,这将非常有用。虽然我尽可能尝试为每个设备类别(iPhone 或 iPad)的每个视图控制器设置一个 nib,以简化开发和维护,但我可以理解开发人员是否希望有时提供不同的布局或不同的功能。

另一个重要的一点是initWithNibName:bundle: 是UIViewController 的指定初始化器。当您调用-[[UIViewController alloc] init] 时,会在后台调用initWithNibName:bundle:。您可以使用符号断点来验证这一点。换句话说,如果你只是想要默认行为,那么你应该可以调用-[[UIViewController alloc] init],然后会隐式调用指定的初始化器。

但是,如果您调用 -[[UIViewController alloc] init] 并没有得到预期的行为,那么您的 UIViewController 子类可能错误地实现了 - (id)init。实现应该类似于以下两个示例之一:

- (id)init

    self = [super init];
    if (self) 
        // custom initialization
    
    return self;

- (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;

【讨论】:

+1:我还想补充一点,您可以为不同的UIViewControllers 使用相同的xib。例如,您可能有一个父类UIViewController,它的子类使用相同的集合IBOutlets 具有相似(但不相同)的功能。在这种情况下,您需要使用initWithNibName:bundle: 方法来指定父xib 文件的名称。【参考方案2】:
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;

【讨论】:

您使用的方法是错误的,因为在从外部创建视图控制器对象时使用 nib 文件名会破坏封装。

以上是关于我啥时候需要调用 -[UIViewController initWithNibName:bundle:]?的主要内容,如果未能解决你的问题,请参考以下文章

我啥时候需要在 Heroku 中使用工作进程

如果在循环中使用 MySQLi 准备好的语句,我啥时候调用 bind_param?

jQuery UI - 我啥时候应该在小部件上使用 destroy 方法

我啥时候需要在 Java 中使用 AtomicBoolean?

CoreData - 我啥时候保存?

我啥时候需要使用四元数?