[英]On iOS, if a view controller has no view yet, why does NSLog(@“self.view is %p”, self.view) crash?
如果在Xcode 4.3.2和AppDelegate.m
使用空应用程序模板创建了新的iOS项目:
self.window.rootViewController = [[FooViewController alloc] init];
在FooViewController
的viewDidLoad
,以下内容:
NSLog(@"self.view is %p", self.view);
NSLog(@"self.view is %@", self.view);
将打印出该视图,因此默认的loadView
看起来将实例化一个视图并将其分配给self.view
。
因此,如果我使用全空方法覆盖loadView
并注释掉上面的第二条NSLog
语句,则我希望第一条NSLog
语句打印出0x0
,但由于该NSLog
行上的内存访问不正确,导致应用程序崩溃。 那为什么会这样?
好吧,在下意识的回答之后,我尝试了一下。 空应用程序模板将没有rootViewController,因此我使用了一个屏幕模板。 运行后,我看到您正在堆栈溢出。 据我所知,在尝试访问self.view时,您正在调用超类的view属性,然后尝试加载该视图以返回视图,即调用viewDidLoad等。 其他NSLog语句执行相同的操作。
UIViewController
的view
属性的文档指出:
因为访问此属性可以导致视图自动加载,所以可以使用
isViewLoaded
方法确定视图当前是否在内存中。
它还具有指向View Controller Life Cycle的链接,其中指出:
在加载周期中发生的步骤如下:
当访问视图控制器的
view
属性并且该视图当前不在内存中时,将触发加载周期。视图控制器调用其
loadView
方法。loadView
方法的默认实现执行以下两项操作之一:
如果视图控制器与情节提要关联,则它将从情节提要中加载视图。
如果视图控制器未与情节
UIView
板关联,则将创建一个空的UIView
对象并将其分配给view
属性。视图控制器调用其
viewDidLoad
方法,以允许您的子类执行任何其他加载时任务。
所以当你说:
因此,如果我使用全空方法覆盖
loadView
您故意中断了生命周期,因为当您覆盖的loadView
版本完成时,它应该已经加载了一个视图。 因为没有,您会崩溃。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.