Guessing at why you might be confused, I'd like to add an explanation of what the second code sample actually does (and why it's not necessary).
NSMutableDictionary *foo = [[NSMutableDictionary alloc] initWithCapacity:0];
I think you are getting confused by this line because this line is often described as "initializing foo". That's a bit misleading. There are technically 2 different entities being changed here -- the new NSMutableDictionary
object is created and the "foo" variable is assigned its address.
The line actually creates a new NSMutableDictionary
object on the heap (your application's dynamic memory area). I'll call this "Dictionary 1". So that this new "Dictionary 1" object on the heap can be found, its memory address is stored in "foo". "foo"s role is to act as an index, so we can find "Dictionary 1".
While we often say: "foo is a dictionary", that's because we are lazy -- the statement is technically wrong. Correctly: "there is a dictionary on the heap and foo stores its memory address so that we can find it and use it".
When you then run the line:
foo = [bar mutableCopy];
you are using the address in "bar" to find a different object (I'll call it "Dictionary 2") in the heap, and make yet another object ("Dictionary 3") on the heap with the same values. If you're keeping count, this is now 3 objects in existence.
After "Dictionary 3" is made, its memory address is then stored in the "foo" variable. This storing into "foo" overwrites the existing memory address (the one that pointed to "Dictionary 1"). This means that we have no remaining pointers to "Dictionary 1" and hence will never be able to find it again. This is why we say "Dictionary 1" has leaked.
I hope you can see from this situation why "Dictionary 1" was never needed (you only ever intended to use "foo" to access the copy, "Dictionary 3").