A lot of people misunderstand the point of
viewDidUnload. That’s because despite the name that implies otherwise, it is not the counterpart of
You should never consider a deallocation in
viewDidUnload a proper balance for an allocation in
viewDidLoad. In fact, you should probably shouldn’t write a
Make your outlets unload automatically
The idea behind
viewDidUnload 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 in UIViewController Class Reference:
When a low-memory condition occurs and the current view controller’s views are not needed, the system may opt to remove those views from memory. This method is called after the view controller’s view has been released and is your chance to perform any final cleanup. If your view controller stores separate references to the view or its subviews, you should use this method to release those references. You can also use this method to remove references to any objects that you created to support the view but that are no longer needed now that the view is gone. You should not use this method to release user data or any other information that cannot be easily recreated.
This was mostly about handling dangling pointers before Automatic Reference Counting (ARC). But now that you’re using ARC and zeroing weak references, the dangling pointers will be cleaned up automatically. No need to write a
Generally, the stuff people put in
viewDidUnload is better handled in
dealloc. The only thing left for
viewDidUnload 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. Really, these caches should be handled in
Clearing out caches
Clearing out cached information fits better into
didReceiveMemoryWarning, so you should write it instead. Apple describes didReceiveMemoryWarning in UIViewController Class Reference, too:
You can override this method to release any additional memory used by your view controller. If you do, your implementation of this method must call the super implementation at some point to allow the view controller to release its view. If your view controller holds references to views in the view hierarchy, you should release those references in the
Not only does writing your cache purging in
didReceiveMemoryWarning better suit the documentation, but you’ll be less confused when you read
didReceiveMemoryWarning in your code than
I’m not taking a ridiculous position here, either.
viewDidUnload is deprecated with iOS 6.
- Use ARC.
- Use weak references for
IBOutletsthat are part of the view hierarchy. They’ll automatically be zeroed when the view is unloaded.
didReceiveMemoryWarningto dispose of anything you can rebuild easily, by (for example) removing all objects from a
NSDictionary. Or, better yet, use
NSCachewhere this behaviour is automatic.
deallocto dispose of any external resources that ARC will handle automatically.
- Don’t even write a
viewDidUnload, unless you’re observing values of outlets with KVO.
If you’re still using Manual Release Retain, none of this applies. You should use retained outlets instead. It’s better to potentially use memory a little too long than to have a dangling pointer. And you should really think about climbing that fence and joining us on the Automatic Reference Counting side. Unbelievably, the grass is just as green here as it looks.