views:

493

answers:

3

I'm currently doing the following to clear out an NSMutableDictionary

[myDictionary release];
myDictionary = [[NSMutableDictionary alloc] init];

The release line doesn't actually release any objects in the dictionary. I can still see all of them on the next line. It isn't until the alloc line is executed that the dictionary is zeroed out. Is there a better way to do it?

A: 

I can't test it at the moment, but have you tried the "removeAllObjects" method of NSMutableDictionary?

http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSMutableDictionary_Class/Reference/Reference.html#//apple_ref/occ/instm/NSMutableDictionary/removeAllObjects

Andy White
You are right. For some reason, it didn't show up in the code hint when I initially tried...so I assumed it wasn't available. I see it now. Thanks.
4thSpace
This doesn't answer the question. `-release` on the dictionary will release all contained objects. 4thSpace has a different problem.
bbum
I just want to echo that if you release a NSDictionary and the objects aren't being released, that means those objects had a retainCount of more than one, which means they're being overretained or not being released properly elsewhere. When you add the objects to the dictionary, are you releasing (or autorelease) them properly?
lucius
+3  A: 

-removeAllObjects will work, as Andy mentioned. However, if any of your dictionary's objects are auto-released, or if the dictionary itself has been autoreleased somewhere along the line, then they won't be dealloc'd until the next time the runloop finishes (when the autorelease pool is drained).

Ben Gottlieb
+15  A: 

You say:

The release line doesn't actually release any objects in the dictionary. I can still see all of them on the next line. It isn't until the alloc line is executed that the dictionary is zeroed out. Is there a better way to do it?

If -release of the mutable dictionary causes the dictionary to be deallocated -- drops the retain count to zero -- then the mutable dictionary will release all contained objects. Always.

Thus, if the objects aren't being released, then this suggested "fix"...

[myDictionary removeAllObjects];
[myDictionary release];
myDictionary = [[NSMutableDictionary alloc] init];

... is a memory leak in that the original instance of NSMutableDictionary will be leaked.

As a result, calling -removeAllObjects will empty the dictionary and release all of the contained objects, but you still have a memory leak that you should figure out and fix.


To be blunt:

If the objects in your dictionary are not being deallocated when the dictionary receives the above -release (without calling -removeAllObjects), then there is a memory leak. It is either:

  1. The objects in the dictionary have been retained an extra time.

  2. There is still an outstanding -retain on the dictionary.

Since you say the objects are being correctly (as in, as expected) deallocated when you call -removeAllObjects, then it must be (2). Look through your code and figure out where there is an extra -retain of the dictionary. You can use the Object Alloc instrument to figure out exactly where all of the retains come from.

bbum
-removeAllObjects does work without calling -release. Are you saying that is still a memory leak?
4thSpace
Yes. The dictionary is being leaked.
bbum