我应该何时使用initWithNibName初始化视图控制器?

Ant*_*nko 48 iphone initialization objective-c uiviewcontroller

我何时应该使用init:,何时应该initWithNibName:bundle:在创建视图控制器时使用?

Rob*_*ier 137

-initWithNibName:bundle:是UIViewController的指定初始值设定项.有些事情最终应该称之为.尽管如此,尽管Apple的例子(在许多情况下有利于简洁性而不是可维护性),但它永远不应该从视图控制器本身外部调用.

您经常会看到如下代码:

MYViewController *vc = [[MYViewController alloc] initWithNibName:@"Myview" bundle:nil];
Run Code Online (Sandbox Code Playgroud)

我说这是不正确的.它将实现细节(NIB的名称和甚至使用NIB的事实)放入调用者.这破坏了封装.正确的方法是:

MYViewController *vc = [[MYViewController alloc] init];
Run Code Online (Sandbox Code Playgroud)

然后,在MYViewController中:

- (instancetype)init
{
   self = [super initWithNibName:@"Myview" bundle:nil];
   if (self != nil)
   {
       // Further initialization if needed
   }
   return self;
}

- (instancetype)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle
{
    NSAssert(NO, @"Initialize with -init");
    return nil;
}
Run Code Online (Sandbox Code Playgroud)

这会将关键实现细节移回对象,并防止调用者意外破坏封装.现在,如果您更改NIB的名称或转移到编程构造,则可以将其固定在一个位置(在视图控制器中),而不是在每个使用视图控制器的位置.

  • 如果这是预期的方式,为什么XCode4为每个空的ViewController类生成一个initWithNibName:bundle:stub,但是没有init方法? (3认同)
  • 模板没有包含类前缀的相同原因,即使您肯定应该为您的类添加前缀,并且模板为您的应用程序委托创建了最愚蠢的名称,这是一个真正令人头疼的问题。当您自动创建属性时,IB 会强制进行 ivar 声明,即使您不应该在新的 ABI 中声明 ivars。模板并不总是最佳实践。它们通常是最不常见的分母,在大多数情况下都有些作用,但没有特别好的地方。Apple 的示例代码最近正在改进,但仍有很长的路要走。 (2认同)
  • @CharlesA如果你使用这种方法,你可以传递`nil`作为nib名称,它将根据视图控制器类来计算它.请参阅"UIViewController -nibName"的文档,该文档解释了它用于查找文件的启发式方法. (2认同)

bpa*_*apa 7

如果您正在使用nib文件进行初始化,请使用initWithNibName!也就是说,您使用Interface Builder创建的文件.

如果您没有使用IB来布局视图,则可以使用init.