Within a view controller, is it necessary to call removeFromSuperview on subviews during viewDidUnload?
Many people say during a view controller's viewDidUnload
method you must remove subviews by calling the removeFromSuperview
method. For example, Three20 does something like this:
-开发者_JAVA百科 (void)viewDidUnload {
[super viewDidUnload];
... snipped ...
[_tableBannerView removeFromSuperview];
TT_RELEASE_SAFELY(_tableBannerView);
[_tableOverlayView removeFromSuperview];
TT_RELEASE_SAFELY(_tableOverlayView);
... snipped ...
}
I understand the reasoning behind this belief: if you call [self.view addSubview:_aView]
in loadView
, you should call [_aView removeFromSuperview]
in viewDidUnload
. The thing is, this doesn't seem necessary. When a view controller's view gets released, its dealloc method automatically releases all of its subviews. My test code shows subviews automatically get released when their superview gets released:
@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
The above code produces the following output:
viewController loadView
view init
view retain
view release
viewDidAppear
viewController dealloc
view release
view dealloc
As you can see, when the view controller's main view gets released, its subviews also get released.
Also, the iOS Developer Library [states](http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html#//apple_ref/doc/uid/TP40007457-CH101-SW4 ): "In the case of a low-memory condition, the default UIViewController behavior is to release the view object stored in the view property if that view is not currently being used." Also: "If you use a declared property to store a reference to your view, and that property uses retain semantics, assigning a nil value to it is enough to release the view."
So, if releasing a view automatically releases its subview, is it really necessary to call removeFromSuperview
during viewDidUnload
?
No, it isn't necessary, the dealloc, as you quite rightly said, will do that for you :) (long post, short answer).
I found it to be necessary in my project. My viewController has a main view (as they all do) and in this case it is defined using a xib (not programmatically allocated and added as a subview). This view has subviews with IBOutlets in the view controller. If, on viewDidUnload, I simply set the IBOutlet properties to nil ( self.mySubView = nil ), then dealloc on that subview is not called. If I first remove it from it's superview (the main view), then dealloc is called.
精彩评论