如何在Objective-C中使用嵌套字典正确发布NSMutableDictionary实例变量?
-
05-07-2019 - |
题
我有一个Objective-C类,看起来像:
@interface myClass : NSObject
{
NSMutableDictionary *aDict;
}
它的setter方法如下:
- (void) setADict: (NSMutableDictionary *) newDict
{
[aDict release];
[newDict retain];
aDict = newDict;
}
我已经创建了一个对象的实例,将数据放入aDict,现在想要摆脱对象,在此过程中清理它的内存。两个问题:
1)我应该在 myClass 的 dealloc 方法中发布 aDict ,如图所示吗?
[aDict release];
=============================================== ==============================
2)我已将几个儿童词典嵌套到 aDict 中,由 keyA 和 keyB 表示,如下所示:
// aDict:
{
keyA = {
keyA1 = "Hello world";
keyA2 = 1234;
};
keyB = {
keyB1 = Earth;
keyB2 = 25000;
};
}
[aDict release] 消息“会在链条中传播”吗?并清理aDict中的所有子词典,包括他们的键/值对象?或者,我是否必须做其他事情来摆脱它们?
解决方案
是
集合对象保留了他们正在收集的东西,因此当取消分配集合时,它会使保留与释放平衡。
然后,如果它所持有的其中一个词典被释放,它也会释放它的键/值对,因为词典是一个集合,而集合对象保留了它们正在收集的东西。
对于数组和集合也是如此。
但是,您的代码中存在错误。你有:
- (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 。第一个会混乱你的自动释放池(可能会或可能不会导致内存膨胀)。第二和第三在安全和财产记忆管理方面是相同的。但是,如果碰巧在自己设置相同的字典,第二个将保存不必要的方法调用。
其他提示
NSMutableDictionary
将在发布时释放所有对象(值)。
NSMutableDictionary
复制密钥并为您添加的每个键/值对发送保留值。可可的做法是,当某些东西保留参考时,它就有责任释放它。
添加条目的方法 词典—是否作为一部分 初始化(适用于所有词典) 或在修改期间(对于可变的 字典)—复制每个关键参数 (密钥必须符合NSCopying 协议)并将副本添加到 字典。每个对应的值 对象接收保留消息 确保它不会被解除分配 在词典通过之前 它