What is the right way to release objects that are placed inside a NSMutableDictionary. (Note obj1 is allocated with initWithFormat to get a true retain count where as obj2 and obj3 are static elements and return a retain count of 2147483647).
My question is looking at the retain count of obj1 at the very end in the following the count is 1. How do I get it to go to 0?:
Code:
NSArray *keys = [[NSArray alloc] initWithObjects:@"key1", @"key2", @"key3", nil];
NSString *obj1 = [[NSString alloc] initWithFormat:@"%@", @"obj1"];
NSString *obj2 = [[NSString alloc] initWithString:@"obj2"];
NSString *obj3 = [[NSString alloc] initWithString:@"obj3"];
NSLog(@"obj1 retain count is %u", [obj1 retainCount]);
NSArray *objs = [[NSArray alloc] initWithObjects:obj1, obj2, obj3, nil];
NSLog(@"after insertion into array obj1 retain count is %u", [obj1 retainCount]);
[obj1 release];
NSLog(@"after release of obj1, obj1 retain count is %u", [obj1 retainCount]);
dict = [[NSMutableDictionary alloc] initWithObjects:objs forKeys:keys];
NSLog(@"after insertion into dictionary obj1 retain count is %u", [obj1 retainCount]);
[objs release];
[keys release];
NSLog(@"after release from objs, obj1 retain count is %u", [obj1 retainCount]);
// Iterate the NSDictionary
for (NSString * key in dict) {
NSLog(@"key: %@ value:%@", key, [dict objectForKey:key]);
}
[dict removeAllObjects];
[dict release];
NSLog(@"after release of dict, obj1 retain count is %u", [obj1 retainCount]);
and the log is:
Code:
Session started at 2011-03-10 10:26:52 -0600.]
2011-03-10 10:26:54.570 [1253:207] obj1 retain count is 1
2011-03-10 10:26:54.572 [1253:207] after insertion into array obj1 retain count is 2
2011-03-10 10:26:54.573 [1253:207] after release of obj1, obj1 retain count is 1
2011-03-10 10:26:54.574 [1253:207] after insertion into dictionary obj1 retain count is 2
2011-03-10 10:26:54.574 [1253:207] after release from objs, obj1 retain count is 1
2011-03-10 10:26:54.575 [1253:207] key: key2 value:obj2
2011-03-10 10:26:54.576 [1253:207] key: key1 value:obj1
2011-03-10 10:26:54.576 [1253:207] key: key3 value:obj3
2011-03-10 10:26:54.577 [1253:207] after release of dict, obj1 retain count is 1
You shouldn't use -retainCount to figure out what is going on. The Apple docs specifically state:
Important: This method is typically of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method.
Back to your question: When you add an object to an NSDictionary, the object is retained. When you remove the object from the dictionary (or dealloc the dictionary), it is released. That's all you need to know. So as long as the object is inside the dictionary, it will remain alive.
Thanks for the info. I read that too however when you finish an app and you are trying to understand why you are getting memory errors I thought that is why they gave us retain count to see what is going on when I'm releasing memory as instructed and the application still says there is a leak.
The retainCount never drops to zero; if the retainCount is one and you release the object then the object gets deallocated and you can no longer safely call any methods on it... this means you shouldn't call retainCount anymore, nor can you expect correct output if you try.
The only time you'll see a zero retainCount is when you are checking the retainCount of a ponter to nil.
If you want to really be sure it is being deallocated correctly, override the dealloc method and log it when its being freed.
A Build & Analyze should help you find issue too.