我对基于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
中发布了一个IBOutlet
,MyViewController
中会发生什么?我能指望在下一个viewDidLoad
中有一个新的引用吗?
换句话说:viewDidUnload
之后视图本身会发生什么?如果再次按下控制器,是否会从Nib中释放并重新加载?或者视图是否会保留在内存中?如果是,是否会在viewDidLoad
之前重置插座?
如果视图保留在存储器中并且插座在viewDidLoad
之前重置(或者每次按下控制器时都会重新加载),我想释放viewDidUnload
中的插座是正确的(即使在第一种情况下这并不重要)。但除此之外(特别是如果视图保留在内存中,并且插座未重置),在viewDidUnload
中释放子视图对于我介绍的用例是错误的,对吗?
1条答案
按热度按时间vlurs2pr1#
从UIViewController documentation的“内存管理”部分:
当内存不足警告发生时,
UIViewController
类会清除它的视图,如果它知道它可以重新加载或重新创建它们。如果发生这种情况,它还会调用viewDidUnload
方法,给予您的代码有机会放弃与您的视图层次结构相关联的任何对象的所有权,包括与nib文件一起加载的对象,在viewDidLoad
方法中创建的对象,以及在运行时延迟创建并添加到视图层次结构中的对象。通常,如果视图控制器包含outlet(包含IBOutlet
关键字的属性或原始变量),则应使用viewDidUnload
方法放弃那些outlet或任何其他不再需要的视图相关数据的所有权。所以你不仅可以在
viewDidUnload
中发布你的插座,这是首选和推荐的方式。是的,当
viewDidLoad
被调用时,你可以指望你的插座指向有效的对象。同样从UIViewController文档中,在viewDidLoad
上:在视图控制器将其关联视图加载到内存中之后调用此方法。