Objective-C:在自动释放的NSDictionary中保留NSDictionary

时间:2011-04-13 00:46:20

标签: objective-c ios memory-management nsdictionary

我有一个很大的NSDictionary,里面有一个较小的NSDictionary。我想自动释放更大的一个,并保留第二个。我的init方法中有这个代码:

// Autoreleased stage dictionary
NSString *plistPath = [[NSBundle mainBundle] pathForResource:map ofType:@"plist"];
NSDictionary *mapDict = [NSDictionary dictionaryWithContentsOfFile:plistPath];

// Owned items
citiesDictionary = [[mapDict objectForKey:@"Cities"] retain];

citiesDictionary在类接口中声明为:

NSDictionary *citiesDictionary;

如果我尝试使用以下行在dealloc中发布citiesDictionary,则会崩溃。

[citiesDictionary release];

但是如果我没有dealloc citiesDictionary,当我解除包含citiesDictionary的类时,我会在Instruments中报告内存泄漏。我承认mapDict在init结束时被释放。这种释放是否会影响citiesDictionary,即使我在其上调用了retain?

如果是这样,我怎样才能保留较小的字典,同时释放较大的字典呢?在分配citiesDictionary时我尝试了不同的东西,但似乎没有任何东西正常工作。我试过的一些方法:

citiesDictionary = [[mapDict objectForKey:@"Cities"] copy];

citiesDictionary = [NSDictionary initWithDictionary:[mapDict objectForKey:@"Cities"]];

甚至

 citiesDictionary = [NSDictionary initWithDictionary:[[mapDict objectForKey:@"Cities"] copy]];

感谢任何帮助。谢谢。

3 个答案:

答案 0 :(得分:1)

将字典复制到citiesDictionary

NSString *plistPath = [[NSBundle mainBundle] pathForResource:map ofType:@"plist"];
NSDictionary *mapDict = [NSDictionary dictionaryWithContentsOfFile:plistPath];
citiesDictionary = [[mapDict objectForKey:@"Cities"] copy];

现在您可以确保拥有字典的副本,即使可以随时释放包含对象。记住然后再发布citiesDictionary。

请注意,使用copy时,即使原始对象为NSDictionary,您也始终会获得不可变NSMutableDictionary。如果需要,使用mutableCopy获取NSMutableDictionary

答案 1 :(得分:1)

你在某个地方过度发布citiesdictionary,看到你已经在init方法中调用了retain。 Map dict只会在自动释放时释放你的citiesdictionary,但不会取消你在init方法中完成的保留。

您应该尝试检查其他方法以获取字典的发布声明,或让静态分析器告诉您。

答案 2 :(得分:0)

感谢您的评论。经过几个小时的撞击我的问题,我发现了导致它的原因。

这完全是我的错:我在与citiesDictionary相关的NSMutableDictionary中插入了一个内存管理有缺陷的自定义类,并释放了其他东西导致内存损坏。

现在,两者

citiesDictionary = [[mapDict objectForKey:@"Cities"] release];

citiesDictionary = [[mapDict objectForKey:@"Cities"] copy];

工作得很好。

PS:StackOverflow霸主:鉴于该问题的解决方案与主要问题完全无关,我应该将此问题投票删除,还是保留以供参考?