I know memory management in iOS is tricky subject to newbies like me, but I was hoping for a clear explanation here on stackoverflow which I could not find anywhere else.
So, pretend I have a property / ivar
@property(nonatomic, retain) UIPopoverController *popOver;
which I'm allocating like this:
self.popOver = [[[UIPopoverController alloc] initWithContentViewController:popOverContent] autorelease];
Now, in my dealloc and viewDidUnload methods, I do both
// in viewDidUnload:
self.popOver = nil;
// in dealloc:
[popOver release];
Question:
- If I do nil / release in viewDidUnload / dealloc, do I really need to autorelease at allocation?
- Vice versa, if I do autorelease at allocation, do I need to nil / release later?
- What's the difference, if any?
Thanks in advance for your time - I'll continue reading, seriously memory management can't be that hard to wrap your head 开发者_StackOverflow中文版around...
Don't be confused by the autorelease in this line:
self.popOver = [[[UIPopoverController alloc] initWithContentViewController:popOverContent] autorelease];
After this statement you effectively own the object because the property setter claimed ownership of it. The autorelease balances the alloc-init
.
So... yes, you need to autorelease at allocation. If you did this (no autorelease), you would leak:
self.popOver = [[UIPopoverController alloc] initWithContentViewController:popOverContent];
Another option is to use a temporary variable instead of autorelease
:
UIPopoverController *temp = [[UIPopoverController alloc] initWithContentViewController:popOverContent];
self.popOver = temp;
[temp release];
Either way you need to release the object in dealloc
.
1 If I do nil / release in viewDidUnload / dealloc, do I really need to autorelease at allocation?
Yes.
2 Vice versa, if I do autorelease at allocation, do I need to nil / release later?
Yes.
In the first case, the auto-releasing is done on behalf of that method. That method doesn't need the popover anymore, so it needs to (auto)release it.
At dealloc
, your object doesn't need the popover anymore. Therefore, you need to release it.
It's very simple. You don't have to consider long-term object ownership; you just need to think very locally, at the level of every method. The decision of releasing it or not doesn't at all depend on whether that object is kept by some other parts of the program. In a method, if you alloc an object and you no longer need it in that method, you (auto)release it.
The dealloc
is a slight exception to the rule. There, you need to release the ownership of all the instance variables.
That's it!
- Yes. But maybe not in this case.
- Yes. But maybe not in this case.
viewDidUnload
is called when the the view is unloaded,dealloc
is called when the view Controller is being destroyed.
In viewDidUnload
you release objects that are used by the view that are not needed anymore and can be recreated in viewDidLoad
. Obvious, since the view is not being displayed it doesn't need to hold on to the objects that are set up by the view controller for it.
In dealloc
you are cleaning up the viewController and here you clear up all it's resources, including those that it has assigned to the view.
In this case, the view does not own the popover controller - it should be owned by the view controller, so there is no need to release it in viewDidUnload
but you do need to release it in the dealloc
.
精彩评论