For iOS apps, using ARC, do we typically release these in viewDidUnload
?
set all instance variables to
nil
set all properties to
nil
Release any context using
CGContextRelease
, CGImage withCGImageRelease
, and color space withCGColorSpaceRelease
(releasing any non object)no special attention needed for
NSMutableArray
ofNSSet
elements: just set the reference to NSMutableArray and NSSet to nil, and each element will be automatically released.
Will doing these handle most memory release under ARC? Are there other items that need to be released as well?
A lot of people misunderstand the point of
viewDidUnload
. In particular, it is not the counterpart toviewDidLoad
. In most cases, your view controller will be deallocated withoutviewDidUnload
being called. For this reason, you should never consider a deallocation inviewDidUnload
a proper balance for an allocation inviewDidLoad
.viewDidUnload
has been deprecated by Apple. Possibly the best argument against using it is its header (which I've wrapped):So what was
viewDidUnload
? The idea behind it is that the view is being unloaded out from behind your view controller. This gives you a chance to detach any pointers to it and clear any information you can rebuild easily. Your view will probably be loaded back in, at which point you'll need to rebuild any caches. Apple describes this:Keep in mind that zeroing out references to objects in
viewDidUnload
should be unnecessary now. If you're using ARC per Apple's recommendations, your view outlets are zeroing weak references. They'll automatically be nilled without you writingviewDidUnload
!Further, clearing out caching information fits better into
didReceiveMemoryWarning
, so you should probably write it instead:Generally, the stuff people put in
viewDidUnload
is better handled inviewDidDisappear
ordealloc
. The only thing left forviewDidUnload
is nilling any of your caches that can be rebuilt without data loss while the view controller is still open, when needed at some point after the view has been reloaded. (And, again, this should be handled indidReceiveMemoryWarning
.) These caches should be built lazily; when your app needs them again, it will quietly rebuild them.So what should you do in
viewDidUnload
? If you're using ARC: Nothing. Don't even write it. In fact, in the time since this answer was written Apple has deprecatedviewDidUnload
.For
CGContextRelease
, theCGContext
resource is not an Objective-C object. (You pointed this out, but I want to repeat it for posterity.) As such, it can not be automatically deallocated by ARC. You are responsible for making sure it's deallocated and nilled just as with the old Manual Retain Release (MRR) memory management scheme.If you put this code in
viewDidUnload
, there is not guarantee it will ever be called. It must go indealloc
. You could put it inviewDidUnload
as well, but…And so:
dealloc
will usually be called withoutviewDidUnload
.The viewDidUnload has a tricky name, it is very easy to know what goes in there if you think about it properly.
First thing you have to know is that the iOS devices have a low memory handling method. This means that when the device needs more memory it will check which of its apps it can free memory from. It does this by calling the ViewDidUnload method (which might be improperly named).
So you are encouraged to set EVERYTHING that can be reconstructed to nil here. (Everything that you created in the viewdidload).
The exceptions are when you really cant afford to lose an object because of the time it might take to get the data or something.
If you do not implement this viewdidload your app will hold onto its items and objects and the iOS wont be able to free anything from it.
SO basically like I said, release (by setting the elements pointing to those objects to nil) everything that you can safely reconstruct in the viewdidload. (which will be called for sure after the view has been unloaded and wants to be loaded again)