Daniel Jalkut responded with a very lucid write-up that represents one of the common points of view on this matter. That view might best be summed up as "crash, baby, crash". If you want to find bugs, the best thing you can do is crash when they happen, that way you know there's a problem and know to look for it. This is not a new idea. I seem to remember a system extension back in the old Mac System 6 or System 7 days that would actually cause your system to crash if your app did a certain bad thing, even if that bad thing didn't cause any noticeable problems in your app. I don't honestly remember the specifics, but it was something to do with the trapping mechanism, I think (anybody know what I'm talking about??). Of course, Apple didn't ship that extension to non-developers.
What makes this a difficult argument is that Daniel is absolutely right… sometimes. There are scenarios where crashing is much better than, say, data loss or data integrity loss. General rules are always problematic, but though I see his point, I'm sticking with "not crashing on customers" being a good rule generally… except when it's not.
In interest of full disclosure, there's actually a third dealloc pattern, albeit a distant third in popularity, but it has definitely become more popular than when I first head of it. In this approach, you assign your instance variable to a stack local variable, then nil the instance variable before releasing it, like so:
In the release-then-nil approach, after you release, there's a tiny window between the release and the assignment of nil where, in multithreaded code, the invalid pointer could still be theoretically be used. This approach prevents that problem by nil'ing first. This point of view represents the opposite end of the spectrum from the one Daniel stated. In this approach, your goal is to code defensively and never let your app crash if you can help it, even in development. If you're a cautious programmer and believe in the Tao of Defensive Programming, then there you go - that's your approach to dealloc.
For me, personally (warning - I'm about to state an opinion) I can't justify the extra code and time of the defensive approach. It's preemptive treatment of a problem so rare that it's almost silly that this discussion is even happening. I've been writing Objective-C since 1999 and I've only once seen a scenario where the dealloc approach would've made a difference in the actual behavior of the application, and that was a scenario created for a debugging exercise in a workshop, so we're really splitting hairs here.
So, here's my final word on dealloc:
- If you already have a strong opinion on which one to use for the type of coding you do, use that one. If not…
- If you prefer that bugs always crash your app so you know about them, use the traditional release-only approach
- If you prefer not to crash if you can help it and prefer to find your bugs using other means, use the newer approach
- If you want your app to crash for you, but not your customers, use the MCRelease() macro or use #if debug pre-processor directives
After all, you're the one who has to live with the consequences of your decision.