正确使用loadView和viewDidLoad与UIViewController没有nibs / xibs

时间:2012-01-16 05:48:19

标签: ios cocoa-touch uiviewcontroller

当我没有笔尖编程时,我觉得我需要调用loadView来初始化我的视图,如下所示:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nil bundle:nil];
    if (self) {
        // Custom initialization
        [self loadView];
    }
    return self;
}

(我设置了nibNameOrNil = nil,因为没有nib。)

然后,我设置了视图,如下所示:

- (void) loadView {
    self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 367)];
    [self viewDidLoad];
}

这是在viewDidLoad中执行其他所有操作。

我仍然不确定我是否应该以这种方式调用loadView和viewDidLoad。它们不会被自动调用。

令人困惑的是UIViewController类引用的文档:

  

loadView讨论

     

您永远不应该直接调用此方法。视图控制器调用   请求view属性但当前为nil时此方法。   如果您手动创建视图,则必须覆盖此方法   用它来创建你的视图。如果你使用Interface Builder来创建   您的视图并初始化视图控制器 - 即初始化   使用initWithNibName:bundle:方法的视图,设置nibName和   直接使用nibBundle属性,或创建视图和视图   在Interface Builder中的控制器 - 然后你不能覆盖它   方法

所以,如果我不应该直接调用它,我不明白如何调用loadView。

  

此方法的默认实现查找有效的nib   信息并使用该信息加载相关的nib文件。   如果未指定nib信息,则创建默认实现   一个简单的UIView对象,并使其成为主视图。

我不明白这是怎么回事 - 创造痛苦UIView。

  

如果您覆盖此方法以手动创建视图,   您应该这样做并将层次结构的根视图分配给   查看属性。 (您创建的视图应该是唯一的实例和   不应与任何其他视图控制器对象共享。)   这种方法的自定义实现不应该调用super。

     

如果要对视图执行任何其他初始化,请执行此操作   所以在viewDidLoad方法中。在iOS 3.0及更高版本中,您还应该   覆盖viewDidUnload方法以释放对该的任何引用   查看或其内容。

好的,到目前为止还没有说明如何调用viewDidLoad。所以对于viewDidLoad:

  

viewDidLoad讨论

     

视图控制器加载后,此方法称为   相关视图到内存中。 无论是什么,都会调用此方法   视图是存储在nib文件中还是已创建   以编程方式在loadView方法中。这种方法最常见   用于对视图执行其他初始化步骤   从nib文件加载。

被什么叫?

由于我的代码中没有自动调用这些方法,因此我不得不认为我必须自己调用它们。但我仍然没有从文档中得到明确的理解,这是正确的做法。

2 个答案:

答案 0 :(得分:34)

正如文档所说,你不应该自己调用这些方法。

这是如何工作的,UIKit的代码将调用你的loadView方法,如果它实际需要在屏幕上显示该控制器的视图层次结构。

具体来说,如果任何代码试图在视图控制器上读取view属性,并且该属性为nil,则UIViewController的代码将调用loadView方法。如果您自己没有实现loadView,那么默认实现将回退到尝试从nib加载视图层次结构。

当您尝试呈现视图控制器且视图为零时,这一切都会自动发生。 (如果您的应用程序正在运行,如果您的视图控制器必须卸载其视图以响应内存压力,这可能会多次发生,您可以获得“免费”的另一种行为,并且您不想给自己打电话)

如果在视图控制器中没有调用这些方法,那么呈现此视图控制器的方式肯定有问题,这会阻止UIViewController中的框架代码调用这些方法。发布该代码,有人可以帮助您找出该错误。

在您尝试修复那个错误之前,您应该从代码中删除这些错误:

[self loadView]
[self viewDidLoad]

然后在您自己的viewDidLoad实现中,您需要使用[super viewDidLoad]

调用超类的实现

请记住,loadView您唯一的责任是将self.view设置为某个有效视图。而已。然后UIKit代码会看到并为您调用viewDidLoad

希望有所帮助。

答案 1 :(得分:7)

Firoze Lafeer 的回答是正确的,我只想展示如何强制加载视图属性正确的方式

(void)self.view;

你不应该这样做! 如果必须,你做错了什么,但不要自己致电-loadView-viewDidLoad任何情况。