之前在创建BNRHypnosisViewController的标签项时覆盖了initWithNibName: bundle:,但是,在BNRAppDelegate.m中是使用init方法来初始化BNRHypnosis- ViewController对象的。这是由于initWithNibName:bundle:是UIViewController的指定初始化方法,向视图控制器发送init消息会调用initWithNibName:bundle:方法并为两个参数都传入nil,因此使用init初始化BNRHypnosisViewController对象也可以正确设置视图控制器的标签项。
BNRHypnosisViewController在创建view属性时没有加载NIB文件,因此不需要指定NIB文件的文件名。那么,如果向一个需要使用NIB文件的视图控制器发送init消息,会发生什么情况?下面就来编写代码测试。
在BNRAppDelegate.m中,修改代码,使用init初始化BNRReminderViewController:
BNRHypnosisViewController *hvc = [[BNRHypnosisViewController alloc] init];
// 获取指向NSBundle对象的指针,该对象代表应用的主程序包
NSBundle *appBundle = [NSBundle mainBundle];
// 告诉初始化方法在appBundle中查找BNRReminderViewController.xib文件
BNRReminderViewController *rvc = [[BNRReminderViewController alloc]
initWithNibName:@"BNRReminderViewController"
bundle:appBundle];
BNRReminderViewController *rvc = [[BNRReminderViewController alloc] init];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
构建并运行应用,运行结果会和之前的完全一样。当init调用initWithNibName:bundle:时,虽然为两个参数都传入了nil,但是UIViewController对象仍然会在应用程序包中查找和当前UIViewController子类同名的XIB文件。因此,当BNRReminderViewController需要创建view时,仍然会载入应用程序包中的BNRReminderViewController.xib。
所以之前的章节中建议读者为UIViewController子类和该子类需要载入的NIB文件取相同的名称。这样当视图控制器需要加载视图时,会自动载入正确的XIB文件。