1

我有一个Objective-C类,看起来像:如何在Objective-C中正确释放NSMutableDictionary实例变量和嵌套字典?

@interface myClass : NSObject 
{ 
    NSMutableDictionary *aDict; 
} 

它的setter方法是这样的:

- (void) setADict: (NSMutableDictionary *) newDict 
{ 
    [aDict release]; 
    [newDict retain]; 
    aDict = newDict; 
} 

我所创建的对象的实例,将数据放入aDict,和现在想摆脱这个对象,在这个过程中清理它的记忆。两个问题:

1)我应该释放aDictmyClass的的dealloc方法,如图?

[aDict release]; 

=========================================== ==================================

2)我已经嵌套几个儿童字典到aDict,通过KEYAKEYB表示,如下所示:

// aDict: 
{ 
    keyA =  { 
     keyA1 = "Hello world"; 
     keyA2 = 1234; 
    }; 
    keyB =  { 
     keyB1 = Earth; 
     keyB2 = 25000; 
    }; 
} 

将一个[aDict释放]消息“传播陶氏链“并清理aDict中的所有子字典,包括键/值对象?或者,我需要做其他的事情来摆脱它们吗?

回答

4

是的。

集合对象保留他们正在收集的东西,所以当集合被释放时,它会将保留与发布平衡。

然后,如果其中一个保存的字典被释放,它也将释放它的键/值对,因为字典是一个集合,集合对象保留他们正在收集的东西。

数组和集合也是如此。

但是,您的代码中存在一个错误。您有:

- (void) setADict: (NSMutableDictionary *) newDict 
{ 
    [aDict release]; 
    [newDict retain]; 
    aDict = newDict; 
}

考虑当newDict是相同的对象aDict。然后你释放字典,它被释放,然后你试图保留它,但哎呀!它不再存在。

有三种方法可以解决这个问题。在这里,他们是:

- (void) setADict: (NSMutableDictionary *) newDict 
    { 
     [aDict autorelease]; 
     [newDict retain]; 
     aDict = newDict; 
    } 

    - (void) setADict: (NSMutableDictionary *) newDict 
    { 
     if (aDict != newDict) { 
     [aDict release]; 
     [newDict retain]; 
     aDict = newDict; 
     } 
    } 

    - (void) setADict: (NSMutableDictionary *) newDict 
    { 
     [newDict retain]; 
     [aDict release]; 
     aDict = newDict; 
    }

我想说的第三个最简单,第二个是最快的一段时间,而首先是MEH。第一个会混淆你的autorelease池(这可能导致内存膨胀或不会导致内存膨胀)。在安全和财产记忆管理方面,第二和第三是同等的。然而,如果你碰巧在自己的字典上设置了相同的字典,第二个将省去不必要的方法调用。

+0

哇,谢谢你的回答,并且非常感谢你抓住错误! :)我正在研究Hillegass的“Mac OX X可可编程”,他有三种完全相同的mem管理习惯。愚蠢的我扭转了保留/释放的顺序,哈哈。我现在不会忘记它,保证! – 2009-09-10 01:42:41

2

NSMutableDictionary将在发布时释放所有对象(值)。

NSMutableDictionary复制密钥并将保留值发送给您添加的每个键/值对。可可的做法是,当某些东西保留参考时,它负责释放它。

See NSMutableDictionary reference

中的方法条目添加到 词典-是否为 初始化(对于所有字典) 或修饰(可变 字典)中的一部分-copy每个键参数 (密钥必须符合到NSCopying 协议),并将副本添加到 字典中。每个对应的值对象接收到一个保留消息到 确保它不会被释放, 在字典通过之前是 它。