I've worked with numerous Delphi developers over the years and worked with a lot of other developers code. I've found that some developers seem happy just to free an object once it is no longer required and some always use FreeAndNil.
My rule on using .Free and FreeAndNil is always use FreeAndNil except when the object is in local scope. For example the only time I use .Free is:
productList := TStringList.Create();
// Do something...
I consider the above to be fine, however recently I was speaking to a developer who said they always use FreeAndNil because what would happen if some other developer added to the procedure and tried to use the object, but check that is was assigned first. In the example above if someone added some code that checked for the assignment and then a block of code that used 'productList'. An error would not occur however the block of code would never be executed. The question here is what is better, the block of code never to execute or an error to occur and the bug is fixed. It is possible that the unit test would detect both early on, and apparently a code coverage tool would also detect that the block of code was never executed (can anyone suggest code coverage tools for Delphi?).
The other argument my colleague had for always using FreeAndNil was if another developer came along and changed the scope of productList and made it into a private or public variable. I consider this to be a weak argument because if a developer did this without reviewing the code then they should not be a Delphi developer.