开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜