在UIViewController的viewDidUnload中发布IBOutlets?

时间:2010-07-06 09:07:19

标签: objective-c iphone uiviewcontroller nib ios

我对在基于Nib的UIViewController s中发生的事情感到有些困惑。生成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];

在这种情况下,我认为持有对子视图的引用的实例变量是否在viewDidUnloaddealloc中发布并不重要,因为dealloc应该在视图中立即调用控制器从堆栈中弹出,所以我不如Apple所说,并在viewDidUnload而不是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中发布子视图对于我提供的用例是错误的,我是否正确?

1 个答案:

答案 0 :(得分:7)

来自UIViewController documentation,内存管理部分:

  

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

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

是的,在调用viewDidUnload时,您可以指望您的商店指向有效对象。再次从UIViewController文档,viewDidLoad

  

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