【发布时间】:2011-06-10 09:06:19
【问题描述】:
许多人说,在视图控制器的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 开发人员库 [状态](http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html#//apple_ref/doc/uid/TP40007457-CH101- SW4 ): “在内存不足的情况下,如果当前未使用该视图,则默认 UIViewController 行为是释放存储在视图属性中的视图对象。”另外:“如果您使用声明的属性来存储对视图的引用,并且该属性使用保留语义,则为其分配 nil 值就足以释放视图。”
那么,如果释放一个视图会自动释放它的子视图,那么在viewDidUnload期间是否真的需要调用removeFromSuperview?
【问题讨论】:
标签: objective-c cocoa-touch uiviewcontroller