After discussing a lot and obviously checking the documentation, these are my thoughts about this topic:

Init methods should be used to allocate data structures needed by your view controller.

The loadView method should be used to allocate and add subviews, as well as to define the view controller’s root view (the well-known self.view). When you override this method, be sure to do not call super (because it is your responsibility to create all that you need). This method should not be used when a nib file defines your view. In this case, use initWithNibName:bundle: to configure your view.

The viewDidLoad method should be used to populate your views with data, because your views are ready for that. Do not create view here, now you know that it is wrong.

The didReceiveMemoryWarning is called when you are almost out of memory, meaning that is time to release all the data that you are able to, but not views. I mean that the best use for this method is to release the data you allocated on viewDidLoad. This method’s default implementation is also responsible for calling viewDidUnload if needed. This is why you should always call it’s super method in the end of your implementation.

The viewDidUnload method is called when you root view is released, meaning that if you are keeping any references to it’s subviews (from loadView) it is time to release them.

The dealloc method is called when your reference count reaches 0 and therefore is the opposite of the init method. So obviously you should release here all that you allocated on your init method. This is also the time to release any objects that for some reason weren’t release before. I know that this is pretty basic stuff, but I would be naive to believe that everybody releases everything that is supposed to be release here.

A good practice is to use your accessors to release properties, instead of calling release followed by nil. I mean, this code is already provided by the @synthesize, why would you write it again?

Ah…and some developers already asked me this, so there it goes: It doesn’t matter if you are using a property or not, you always have to release instance variables in the end. Be assigning nil through it’s accessor or releasing the variable itself.