For a view controller, any outlets that you set in Interface Builder must be released
and set to nil in viewDidUnload, and must also be released in dealloc.
(see: When should I release objects in viewDidUnload rather than in dealloc?)
One of the most important reasons for implementing [viewDidUnload] is that UIViewController subclasses commonly also contain owning references to various subviews in the view hierarchy. These properties could have been set through IBOutlets when loading from a nib, or programmatically inside loadView [emphasis added], for instance.
My question is, do we really need to implement viewDidUnload for subviews in the view hierarchy that are created programmatically in loadView (without Interface Builder)?
It depends how you created them and if you need to reference them elsewhere.
For example:
In the above case you would not need to implement viewDidUnload because someButton is autoreleased within loadView.
Another example:
In this example you would want to use viewDidUnload, as you have another reference to someButton hanging around. You want viewDidUnload to release that button and reset the reference so you don’t improperly use it as well as free up the memory. In this case you would also want to release the button in the dealloc method as well, in case viewDidUnload is never called.