I have been under the assumption for a while that viewDidUnload
is always called when a controller is deallocated. Is this a correct assumption?
I've just been exploring some odd things, and set a breakpoint in my controller's viewDidUnload
and it's dealloc
. It appears that dealloc
is called, but the viewDidUnload
method is never called. I even added a self.view = nil
to my dealloc
and it still didn't seem to call it.
Does this mean that retained view objects I have been releasing in the viewDidUnload
method also need to be released in my dealloc
method to be sure they really go away?
I know there are many other questions on StackOverflow about viewDidUnload
, but none specifically address this issue about duplication of release statements between the 2 methods.
A more concrete exmaple in a fresh project on the 3.1.2 SDK:
@implementation TestViewController
@synthesize label;
- (IBAction)push {
TestViewController *controller = [[[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil] autorelease];
[self.navigationController pushViewController:controller animated:YES];
}
- (void)viewDidUnload {
self.label = nil;
NSLog(@"viewDidUnload was called");
}
- (void)dealloc {
[super dealloc];
NSLog(@"label retain count: %i", [label retainCount]);
}
@end
My app delegate creates a simple navigation controller with one of these as it's root controller. When I tap the button linked to push
3 times, and then hit the back button three times, the following output is generated.
ViewDidUnloadTest[2887:207] label retain count: 2
ViewDidUnloadTest[2887:207] label retain count: 2
ViewDidUnloadTest[2887:207] label retain count: 2
Which is 2 higher that I would think it would be. Retained once by the view and once by the controller. But after the dealloc
I would have expected the view to be gone releasing my label, and the controller to be gone calling viewDidUnload
and releasing it. Although there may be an autorelease
in there throwing off the count at this point.
But at least it's clear that viewDidUnload
is not getting called at all, which contrary to this answer here: http://stackoverflow.com/questions/1768076/are-viewdidunload-and-dealloc-always-called-when-tearing-down-a-uiviewcontroller
Perhaps I should simply call [self viewDidUnload]
in all my dealloc methods on controllers? Worse than can happen is that I set a property to nil twice, right?