You are confusing two very different things. A zombie is not a dangling pointer. It is something you create in a debugging situation to track down a dangling pointer (i.e. to debug).
A dangling pointer, as I think you understand, is caused when object A has a reference to object B, but object B is released in such a way that its retain count goes down to zero and goes out of existence.
A typical scenario is that we assign a Cocoa object a delegate
and the delegate
subsequently goes out of existence. Many Cocoa delegate
properties are traditionally nonarc weak (assign
), so if the Cocoa object now tries to talk to its delegate
, we can crash.
As you rightly say, the solution is to assign nil
to the delegate
property when the delegate object goes out of existence. Fortunately, that scenario is becoming less likely all the time, because Apple is replacing assign
delegates with weak
(arcweak) delegates throughout Cocoa.
But dangling pointers can also happen through issues with threading.
Crashes caused by dangling pointers can be very hard to track down, because the crash, when it comes, is often long after the release that caused the pointer to dangle. Zombies are a debugging tool where there are no dangling pointers. Instead, when an object goes out of existence, a zombie object takes its place at the same memory address. In effect, all our memory now leaks, but this is worth while for testing purposes because we may be able to track down the cause of our crash. The zombie object does only one thing: it screams if anyone touches it, and it reports what kind of object it replaced. Thus we can detect, in good order, an attempt to send a message by way of what would have been a dangling pointer.