许多人说在视图控制器的 viewDidUnload
方法中,必须通过调用 removeFromSuperview
方法来删除子视图。例如,Three20 这样做:
- (void)viewDidUnload {
[super viewDidUnload];
... snipped ...
[_tableBannerView removeFromSuperview];
TT_RELEASE_SAFELY(_tableBannerView);
[_tableOverlayView removeFromSuperview];
TT_RELEASE_SAFELY(_tableOverlayView);
... snipped ...
}
我理解这种信念背后的原因:如果你在loadView
中调用[self.view addSubview:_aView]
,那么你应该在viewDidUnload
中调用[_aView removeFromSuperview]
。然而事实是,这似乎并不必要。当视图控制器的视图被释放时,它的dealloc方法会自动释放所有子视图。我的测试代码显示,当父视图被释放时,子视图会自动被释放:
@interface TestView : UIView
@end
@implementation TestView
- (id)retain {
NSLog(@"view retain");
return [super retain];
}
- (void)release {
NSLog(@"view release");
[super release];
}
- (id)init {
NSLog(@"view init");
return (self = [super init]);
}
- (void)dealloc {
NSLog(@"view dealloc");
[super dealloc];
}
@end
@interface TestViewController : UINavigationController
@end
@implementation TestViewController
- (void)loadView {
NSLog(@"viewController loadView");
[super loadView];
[self.view addSubview:[[TestView new] autorelease]];
}
- (void)viewDidUnload {
NSLog(@"viewController viewDidUnload");
[super viewDidUnload];
}
- (void)viewDidAppear:(BOOL)animated {
NSLog(@"viewDidAppear");
[super viewDidAppear:animated];
[self dismissModalViewControllerAnimated:YES];
}
- (void)dealloc {
NSLog(@"viewController dealloc");
[super dealloc];
}
@end
上述代码生成以下输出:
viewController loadView
view init
view retain
view release
viewDidAppear
viewController dealloc
view release
view dealloc
正如您所看到的,当视图控制器的主视图被释放时,它的子视图也会被释放。
此外,iOS开发者库声明:“在低内存情况下,默认的UIViewController行为是释放存储在视图属性中的视图对象,如果该视图当前未被使用。” 另外:“如果您使用一个已声明的属性来存储对视图的引用,并且该属性使用保留语义,将nil值分配给它就足以释放该视图。”
因此,如果释放视图会自动释放其子视图,那么在viewDidUnload期间调用removeFromSuperview是否真的有必要呢?