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

当我没有笔尖编程时,我的印象是我需要调用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。)

然后,我build立了这样的观点:

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

这是做viewDidLoad中的一切。

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

令人困惑的是在UIViewController类的参考文档中:

loadView讨论

你不应该直接调用这个方法。 视图控制器在请求视图属性时调用此方法,但当前为零。 如果您手动创build视图,则必须重写此方法并使用它来创build视图。 如果使用Interface Builder创build视图并初始化视图控制器,即使用initWithNibName:bundle:方法初始化视图,则直接设置nibName和nibBundle属性,或者在Interface Builder中创build视图和视图控制器 – 那么你不能重写这个方法。

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

此方法的默认实现查找有效的笔尖信息,并使用该信息加载关联的笔尖文件。 如果没有指定nib信息,则默认实现将创build一个普通的UIView对象,并使其成为主视图。

我不明白这是如何工作 – 创build一个痛苦UIView。

如果您为了手动创build视图而重写此方法,则应该这样做,并将层次结构的根视图分配给视图属性。 (您创build的视图应该是唯一的实例,不应该与任何其他视图控制器对象共享。)您自定义的此方法的实现不应该调用super。

如果您想对视图执行任何额外的初始化,请在viewDidLoad方法中执行此操作。 在iOS 3.0及更高版本中,您还应该重写viewDidUnload方法以释放对视图或其内容的任何引用。

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

viewDidLoad讨论

在视图控制器将相关视图加载到内存之后调用此方法无论视图是存储在nib文件中还是以编程方式在loadView方法中创build, 都会调用此方法。 此方法最常用于对从nib文件加载的视图执行附加的初始化步骤。

叫什么?

由于这些方法在我的代码中没有被自动调用,我只能认为我必须自己调用它们。 但是我仍然没有从文件中得到清楚的理解,这是正确的。

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

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

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

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

如果这些方法没有在你的视图控制器中被调用,那么你如何呈现这个视图控制器就会出现问题,这会阻止UIViewController中的框架代码调用这些方法。 发布代码和某人可以帮助你找出这个错误。

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

 [self loadView] [self viewDidLoad] 

然后在你自己的viewDidLoad的实现中,你会想调用超类的实现[super viewDidLoad]

请记住,在loadView您只需将self.view设置为某个有效视图 。 而已。 UIKit代码将会看到并为你调用viewDidLoad

希望有所帮助。

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

 (void)self.view; 

你不应该这样做! 如果你必须,你做错了什么,但不要在任何情况下调用-loadView-viewDidLoad