1

我有一个 Objective-C 类,它看起来像:

@interface myClass : NSObject
{
    NSMutableDictionary *aDict;
}

它的 setter 方法如下所示:

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

我已经创建了对象的一个​​实例,将数据放入 aDict,现在想要摆脱该对象,在进程中清理它的内存。两个问题:

1) 我应该在myClassdealloc方法中释放aDict吗,如图所示?

[aDict release];

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

2)我已经将几个子字典嵌套到aDict中,由keyAkeyB表示,如下所示:

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

[ aDict release]消息是否会“沿链传播”并清理 aDict 内的所有子字典,包括它们的键/值对象?或者,我是否必须做其他事情才能摆脱它们?

4

2 回答 2

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。第一个会弄乱你的自动释放池(这可能会也可能不会导致内存膨胀)。第二和第三在安全和属性内存管理方面是等效的。但是,如果您碰巧在自身上设置了相同的字典,则第二种方法将为您节省不必要的方法调用。

于 2009-09-10T00:34:08.283 回答
2

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

NSMutableDictionary为您添加的每个键/值对复制键并将保留发送到值。Cocoa 的做法是,当某些东西保留引用时,它负责释放它。

请参阅 NSMutableDictionary 参考

向字典添加条目的方法——无论是作为初始化的一部分(对于所有字典)还是在修改期间(对于可变字典)——复制每个键参数(键必须符合 NSCopying 协议)并将副本添加到字典。每个对应的值对象都会收到一条保留消息,以确保在字典使用完之前不会释放它。

于 2009-09-10T00:45:15.473 回答