7

我对在基于 Nib 的UIViewControllers 中究竟发生了什么感到有点困惑。生成UIViewController子类时,模板在方法中包含非常具体的注释viewDidUnload

// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;

这适用于哪些子视图?

  • 我初始化的那些viewDidLoad?(我会说是的)
  • 我初始化的那些initWithNibName?(我会说不)
  • 引用 Nib 中对象的 IBOutlets?

如果我像这样使用视图控制器:

MyViewController *controller = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
[controller release];

在这种情况下,我认为保存对子视图的引用的实例变量是否被释放并不重要,viewDidUnload或者一旦视图控制器从堆栈中弹出就应该被调用,所以我不妨按照苹果所说的去做并释放dealloc实例dealloc变量 onviewDidUnload而不是dealloc.

但是假设我用作MyViewController可能被多次推送的实例变量:

if(self.myViewController == nil) {
    self.myViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
}
//Change some state which should be reflected in the view
self.myViewController.someProperty = someValue;
[self.navigationController pushViewController:self.myViewController animated:YES];

MyViewController如果我在 中释放 IBOutlet会发生什么viewDidUnload?我可以指望在下一个对它有新的引用viewDidLoad吗?

换句话说:在 之后视图本身会发生什么viewDidUnload?如果再次推动控制器,它是否会从 Nib 释放并重新加载?或者视图是否保留在内存中?如果是这样,网点之前是否会重新设置viewDidLoad

如果视图保留在内存中并且插座在之前重新设置viewDidLoad或每次按下控制器时都重新加载,我认为释放插座是正确的viewDidUnload(即使在第一种情况下它并不重要)。但除此之外(特别是如果视图保留在内存中并且未重新设置插座),viewDidUnload对于我提出的用例来说,释放子视图是错误的,我正确吗?

4

1 回答 1

7

UIViewController 文档,内存管理部分:

当发生内存不足警告时,如果UIViewController该类知道以后可以重新加载或重新创建它们,则会清除其视图。如果发生这种情况,它还会调用该viewDidUnload方法,让您的代码有机会放弃与视图层次结构关联的任何对象的所有权,包括使用 nib 文件加载的对象、在您的viewDidLoad方法中创建的对象以及在运行时延迟创建的对象和添加到视图层次结构中。通常,如果您的视图控制器包含出口(包含IBOutlet关键字的属性或原始变量),您应该使用该viewDidUnload方法放弃这些出口或您不再需要的任何其他与视图相关的数据的所有权。

因此,您不仅可以在 中发布网点viewDidUnload,而且这是首选和推荐的方式。

是的,你可以指望让你的出口在viewDidLoad被调用时指向有效的对象。再次来自 UIViewController 文档,关于viewDidLoad

在视图控制器将其关联的视图加载到内存后调用此方法。

于 2010-07-06T12:07:28.077 回答