Objective-C: Retaining a NSDictionary inside an autoreleased NSDictionary
I have a big NSDictionary with a smaller NSDictionary inside. I want to autorelease the bigger one, and retain the second. I have this code in my init method:
// Autoreleased stage dictionary NSString *plistPath = [[NSBundle mainBundle] pathForResource:map ofType:@"plist"]; NSDictionary *mapDict = [NSDictionary dictionaryWithContentsOfFile:plistPath]; // Owned items citiesDictionary = [[mapDict objectForKey:@"Cities"] retain];
citiesDictionary is declared in the class interface as an:
NSDictionary *citiesDictionary;
If I try to release citiesDictionary in dealloc using the following line it crashes.
[citiesDictionary release];
But if I don't dealloc citiesDictionary, I get a memory leak reported in Instruments when I dealloc the class containing citiesDictionary. I acknowledge that mapDict is being deallocated at the end of init. Does this deallocation affects citiesDictionary even though I called retain on it?
If so, how can I keep the smaller dictionary while freeing the bigger containing one? I tried different things when assigning cities开发者_如何学JAVADictionary, but nothing seems to work correctly. Some of the approaches I tried:
citiesDictionary = [[mapDict objectForKey:@"Cities"] copy];
and
citiesDictionary = [NSDictionary initWithDictionary:[mapDict objectForKey:@"Cities"]];
and even
citiesDictionary = [NSDictionary initWithDictionary:[[mapDict objectForKey:@"Cities"] copy]];
Copy the dictionary to citiesDictionary
.
NSString *plistPath = [[NSBundle mainBundle] pathForResource:map ofType:@"plist"];
NSDictionary *mapDict = [NSDictionary dictionaryWithContentsOfFile:plistPath];
citiesDictionary = [[mapDict objectForKey:@"Cities"] copy];
Now you can be sure to have copy of the dictionary even though the containing object can be released at any time. Remember then to also subsequently release the citiesDictionary.
Note when using copy
that you will always get an immutable NSDictionary
even if the original object was an NSMutableDictionary
. Use mutableCopy
to obtain an NSMutableDictionary
if needed.
You're overreleasing citiesdictionary somewhere, seeing you have already called retain in the init method. Map dict will only release your citiesdictionary once when it is autoreleased, but will not cancel the retain you have done in the init method.
You should try to check your other methods for a release statement to your dictionary, or have the static analyzer tell you.
It was completely my fault: I was inserting a memory-management flawed custom class inside a NSMutableDictionary related to the citiesDictionary, and freeing that other thing was causing the memory to go corrupt.
Now, both
citiesDictionary = [[mapDict objectForKey:@"Cities"] release];
and
citiesDictionary = [[mapDict objectForKey:@"Cities"] copy];
work perfectly fine.
精彩评论