Reputation: 7103
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.
Upvotes: 1
Views: 1523
Reputation: 299605
You never, ever call -dealloc
directly. The only thing close is the call to [super dealloc]
, and that should only be called in your own dealloc
. If you call dealloc
directly, 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 release
the mapView
. 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 of OnePlaceViewController
'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 init
and dealloc
(and init
is 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....)
Upvotes: 1
Reputation: 5245
A couple of things:
1) You should always release
after pushing a view controller onto a navigation controller or any other "container" view controller, as these controllers will retain
on the view controller you just alloc
ed. The exception is if you want to store the view controller in an ivar for later, in which case you should keep the retain. In this case you're likely getting the overreleased crash because something in your OnePlaceViewController
's dealloc
method is being overreleased. Check that method for objects that you have not retained on.
2) Be careful in your use of the words "view" and "view controller". A view is an abstraction of a drawing space, and a view controller is an object that contains the logic to manage a view. If you're using IB and allocating a view controller via a nib (which you appear to be) then all of the view memory management for that view controller should be handled automatically. I would take a good look at whatever objects you're using besides the view in OnePlaceViewController
to see if anything is released twice.
Upvotes: 1
Reputation: 4282
First of all, you should read the memory mamagement programming guide from Apple.
Second, you should never be calling [anObject dealloc] directly. The exception is [super dealloc] inside a dealloc method. You will be using release, and autorelease when corresponds.
Again, abide by the memory management rules from Apple and you will be just fine
Upvotes: 1