我啥时候需要调用 -[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:我还想补充一点,您可以为不同的UIViewController
s 使用相同的xib。例如,您可能有一个父类UIViewController
,它的子类使用相同的集合IBOutlet
s 具有相似(但不相同)的功能。在这种情况下,您需要使用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:]?的主要内容,如果未能解决你的问题,请参考以下文章
如果在循环中使用 MySQLi 准备好的语句,我啥时候调用 bind_param?
jQuery UI - 我啥时候应该在小部件上使用 destroy 方法