If I have a stack of views controlled by a view controller, and a view’s dealloc (containing [super dealloc]) method is called when I pop the view from the view stack, does that mean I don’t have to release the view controller where it was created?
I ask because I originally was releasing the views after creation and pushing them to the navigation controller, except I continually get “overreleased” errors when I include [viewController release]. Without that statement, the navigation controller works fine, and the analyze function in XCode doesn’t complain about a potential memory leak.
Any sort of explanation would be greatly appreciated!
Edit: An example of where this occurs
OnePlaceViewController *mapView = [[OnePlaceViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:mapView animated:YES];
Normally I would call [mapView release] after I push to the navigation controller (in my understanding of memory management, anyway), but I end up with a crash later in my app if I keep the line in there.
You never, ever call
-deallocdirectly. The only thing close is the call to[super dealloc], and that should only be called in your owndealloc. If you calldeallocdirectly, you should expect a crash later.If you meant to say
[viewController release], then that indicates you have a mismatch somewhere of retains and releases. You should release what you retain. See Three Magic Words for more explanation and links to the full docs. They’re not hard, but you must follow them consistently.EDIT If you alloc, you should release when you’re done with the object. This doesn’t mean “when the object should be destroyed.” This means “when you are done with the object.” If other parts of the system still want the object, they’ll retain it. Retain what you want, release what you’re done with.
In your example, you should
releasethemapView. You’ve handed it to the nav controller, and now you’re done with it. If you’re crashing in releasing it, you’re probably over-releasing somewhere else. The most likely place is one ofOnePlaceViewController‘s ivars, or one of it’s owned-object’s ivars.Start with the static analyzer (Cmd-Shift-B in Xcode 4), and see if it finds your overrelease. It doesn’t do a good job of finding ivar overreleases, though. Then, make sure you always use accessors except in
initanddealloc(andinitis controversial). Accessing your ivars directly is the #1 cause of messed up memory management, which is the #1 cause of crashes.Do not just randomly insert and remove retains and releases. You will tie yourself up in knots. If you fix the crashes, you’ll leak. When you fix the leaks you’ll crash. You have to find the mistake and fix it. There’s no workaround until you upgrade to a system that includes ARC (at which point all of this magically goes away….)