Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/44.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 何时应该使用initWithNibName初始化视图控制器?_Iphone_Objective C_Uiviewcontroller_Initialization - Fatal编程技术网

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

Iphone 何时应该使用initWithNibName初始化视图控制器?,iphone,objective-c,uiviewcontroller,initialization,Iphone,Objective C,Uiviewcontroller,Initialization,创建视图控制器时,我应该何时使用init:以及何时使用initWithNibName:bundle:呢?如果您是。。。使用nib文件初始化!即,使用Interface Builder创建的文件 如果您不使用IB来布局视图,则可以使用init-initWithNibName:bundle:是UIViewController的指定初始值设定项。最终应该有人叫它。也就是说,尽管苹果的例子(在许多情况下,简洁性优于可维护性),但它永远不应该从视图控制器本身之外调用 您经常会看到这样的代码: MYView

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

如果您是。。。使用nib文件初始化!即,使用Interface Builder创建的文件


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

-initWithNibName:bundle:
是UIViewController的指定初始值设定项。最终应该有人叫它。也就是说,尽管苹果的例子(在许多情况下,简洁性优于可维护性),但它永远不应该从视图控制器本身之外调用

您经常会看到这样的代码:

MYViewController *vc = [[MYViewController alloc] initWithNibName:@"Myview" bundle:nil];
我说这是不正确的。它将实现细节(NIB的名称和甚至使用NIB的事实)放入调用方。这破坏了封装。正确的方法是:

MYViewController *vc = [[MYViewController alloc] init];
然后,在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;
}

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

在没有NIB/xib文件时使用init,例如,UI是通过编码创建的

使用initWithNibName,如果我们有一个nib/xib或同一个控制器共享超过1个nib/xib

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
     self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil];
 } else {
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil];
 }

这就是我的想法。

只要xib与视图控制器类具有相同的名称,就可以调用init。封装是不必要的。这样可以节省打字时间,但可能无法达到清晰的效果

 NUDMainViewController *mainVC = [[NUDMainViewController alloc] init];

如果这是预期的方式,为什么XCode4会为每个空的ViewController类生成initWithNibName:bundle:stub,而没有init方法?同样的原因是模板没有包含类前缀,即使你肯定要给你的类加前缀,而且模板会为你的应用程序委托创建最愚蠢的名称,这真是一个让人头疼的问题。当您自动创建属性时,IB强制执行ivar声明,即使您不应该在新ABI中声明ivar。模板并不总是最佳实践。它们通常是最不常见的分母,在大多数情况下都能起到一定的作用,但没有哪个地方特别好。苹果的示例代码最近有所改进,但仍有一段路要走。如果您遵循将NIB命名为与类相同的约定,那么此代码运行良好:
-(id)init{return[super initWithNibName:NSStringFromClass([self class])bundle:nil];}
@CharlesA如果您使用这种方法,您可以将
nil
作为nib名称传递,它将根据视图控制器类计算出来。请参阅
UIViewController-nibName
的文档,其中解释了它用于查找文件的启发式方法。我已经使用这种方法一段时间了。太棒了,谢谢你,罗布!您应该更改此问题的选定答案。您知道,如果在nib名称中添加~iphone或~ipad,您只需使用nibName@“ViewController”调用init,它就会选择正确的答案。