在iOS上,如果视图控制器还没有视图,为什么NSLog(@“self.view是%p”,self.view)崩溃?

时间:2012-05-24 19:32:57

标签: iphone ios uiview uiviewcontroller

如果在Xcode 4.3.2和AppDelegate.m中使用空应用模板创建了新的iOS项目:

self.window.rootViewController = [[FooViewController alloc] init];

以及FooViewController的{​​{1}},以下内容:

viewDidLoad

将打印出视图,因此看起来默认NSLog(@"self.view is %p", self.view); NSLog(@"self.view is %@", self.view); 将实例化视图并将其分配给loadView

因此,如果我使用全空方法覆盖self.view并注释掉上面的第二个loadView语句,我希望第一个NSLog语句打印出NSLog,但是,由于在0x0行的内存访问不良,应用程序崩溃了。为什么会这样?

2 个答案:

答案 0 :(得分:5)

好吧,经过一次下意识和明显错误的回答后,我尝试了这个。 Empty App模板没有rootViewController,因此我使用了单个屏幕模板。运行后,我看到你正在堆栈溢出。在尝试访问self.view时,您正在调用超类上的view属性,然后尝试加载视图以便返回它,就我所见,它正在调用viewDidLoad等。另一个NSLog语句也是如此。

答案 1 :(得分:2)

view property in UIViewController州的文档:

  

由于访问此属性可能导致视图自动加载,因此您可以使用isViewLoaded方法确定视图当前是否在内存中。

它还有The View Controller Life Cycle的链接,其中指出:

  

加载周期中发生的步骤如下:

     
      
  1. 访问视图控制器的view属性并且视图当前不在内存中时,将触发加载周期。

  2.   
  3. 视图控制器调用其loadView方法。 loadView方法的默认实现可以执行以下两项操作之一:

         
        
    • 如果视图控制器与故事板相关联,则会从故事板中加载视图。

    •   
    • 如果视图控制器未与故事板关联,则会创建一个空的UIView对象并将其分配给view属性。

    •   
  4.   
  5. 视图控制器调用其viewDidLoad方法以允许您的子类执行任何其他加载时任务。

  6.   

所以当你说:

  

所以如果我用全空方法覆盖loadView

你故意打破生命周期,因为当你的被覆盖的loadView版本完成时,它应该已经加载了一个视图。因为它没有,你会崩溃。