Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

- (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?

like image 340
David H Avatar asked Jun 10 '11 09:06

David H


1 Answers

No, it isn't necessary, the dealloc, as you quite rightly said, will do that for you :) (long post, short answer).

like image 153
Simon Lee Avatar answered Oct 21 '22 06:10

Simon Lee