我遇到的情况似乎暗示不然。在下面的代码片段中,如果我删除行:self.navigationController = nav,根控制器的视图将不会显示,向我建议addSubview可能实际上不会保留视图,否则建议。有什么想法吗?
- (void)applicationDidFinishLaunching:(UIApplication *)application {
self.testViewController = [[TestViewController alloc] initWithNibName:@"TestView" bundle: [NSBundle mainBundle]];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self.testViewController];
self.navigationController = nav; //<-- if this line is removed, test view won't show up
[window addSubview:nav.view];
[nav release];
}
答案 0 :(得分:24)
这一行:
[window addSubview:nav.view];
不会立即向屏幕添加视图。它在一个可能不同的线程上的某个未来的运行循环中由OS显示。实际的实现我们无法确定。
这就是为什么Apple定义了像viewDidAppear / viewWillAppear这样的委托方法,否则我们就不会需要它们,因为我们可以准确地知道这些事件何时发生。
此外,如您所说,添加子视图确实保留了视图。但 NOT 会保留视图控制器或导航控制器。由于导航控制器将保留任何添加的视图控制器,因此我们不必使用ivar支持它们。
但是,您对导航控制器的引用必须持久超出方法的范围。或者根据你的代码,它可以被解除分配或丢失它的引用。
因此,您必须使用ivar保留对导航控制器的引用,并将其设置为:
self.navigationController = nav;
因此,即使nav.view包含指向testViewController.view的指针,该应用程序也没有引用导航控制器,也没有引用视图。结果是一个空白屏幕。
为了使这更加明显,它不是保留/释放问题,您实际上是在使用以下方法泄漏:
self.testViewController = [[TestViewController alloc] initWithNibName:@"TestView" bundle: [NSBundle mainBundle]];
您需要通过以下方式自动发布以平衡您的保留/发布:
self.testViewController = [[[TestViewController alloc] initWithNibName:@"TestView" bundle: [NSBundle mainBundle]] autorelease];
因此,这意味着您的视图从未在您运行此代码时被解除分配。这进一步向我们保证,您的问题确实是一个失去的参考。
答案 1 :(得分:2)
问题可能不是视图没有保留,而是控制器没有被保留。
没有这一行:
self.navigationController = nav
什么都没有保留导航控制器。让视图比控制器更长是很奇怪的。
答案 2 :(得分:0)
这对我来说看起来不是一个保留/释放问题。如果您注释掉self.navigationController = nav;
,则视图将不会显示,因为在下一行中,[window addSubview:self.navigationController.view]
将不会设置您的self.navigationController属性。它可能是零或者它会崩溃但是如果没有更多的代码就无法确定。