ios 在UIViewController的视图DidUnload中释放IBOutlets?

mdfafbf1  于 2023-01-27  发布在  iOS
关注(0)|答案(1)|浏览(124)

我对基于Nib的UIViewController中到底发生了什么有点困惑。当生成UIViewController子类时,模板在viewDidUnload方法中包含一个非常具体的注解:

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

这适用于哪些子视图?

  • 我在viewDidLoad中初始化的那些?(我会说是的)
  • 我在initWithNibName中初始化的那些?(我会说没有)
  • 引用Nib中对象的IBOutlet

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

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

在这种情况下,我认为包含子视图引用的示例变量是在viewDidUnload还是dealloc中发布并不重要,因为视图控制器从堆栈中弹出时,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];

如果我在viewDidUnload中发布了一个IBOutletMyViewController中会发生什么?我能指望在下一个viewDidLoad中有一个新的引用吗?
换句话说:viewDidUnload之后视图本身会发生什么?如果再次按下控制器,是否会从Nib中释放并重新加载?或者视图是否会保留在内存中?如果是,是否会在viewDidLoad之前重置插座?
如果视图保留在存储器中并且插座在viewDidLoad之前重置(或者每次按下控制器时都会重新加载),我想释放viewDidUnload中的插座是正确的(即使在第一种情况下这并不重要)。但除此之外(特别是如果视图保留在内存中,并且插座未重置),在viewDidUnload中释放子视图对于我介绍的用例是错误的,对吗?

vlurs2pr

vlurs2pr1#

UIViewController documentation的“内存管理”部分:
当内存不足警告发生时,UIViewController类会清除它的视图,如果它知道它可以重新加载或重新创建它们。如果发生这种情况,它还会调用viewDidUnload方法,给予您的代码有机会放弃与您的视图层次结构相关联的任何对象的所有权,包括与nib文件一起加载的对象,在viewDidLoad方法中创建的对象,以及在运行时延迟创建并添加到视图层次结构中的对象。通常,如果视图控制器包含outlet(包含IBOutlet关键字的属性或原始变量),则应使用viewDidUnload方法放弃那些outlet或任何其他不再需要的视图相关数据的所有权。
所以你不仅可以在viewDidUnload中发布你的插座,这是首选和推荐的方式。
是的,当viewDidLoad被调用时,你可以指望你的插座指向有效的对象。同样从UIViewController文档中,在viewDidLoad上:
在视图控制器将其关联视图加载到内存中之后调用此方法。

相关问题