【发布时间】:2011-03-12 05:23:28
【问题描述】:
对于基于 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 就会被调用所以我不妨像苹果说的那样在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 中的子视图是错误的,我正确吗?
【问题讨论】:
-
更新:请注意,
viewDidUnload将在 iOS 6 中被弃用,因为显然它让很多开发人员(不仅仅是我)感到困惑,而且他们经常以某种方式错误地使用它,当开发人员没有考虑到内存警告时,这将导致他们的应用程序崩溃/行为不端......
标签: objective-c iphone uiviewcontroller nib ios