NSMutableDIctionary中NSData的可变副本导致内存泄漏

时间:2011-03-17 14:44:49

标签: objective-c cocoa-touch nsdata memory-leaks nsmutabledictionary

在我的代码中,我在viewDidAppear中定义了一个NSDictionary,如下所示:

  

dataDictionary = [[NSMutableDictionary alloc] init];

然后在loadData方法中,我加载了NSDictionary的可变副本,如下所示:

      [dataDictionary setObject:[receivedData mutableCopy] forKey:[theConnection description]];

稍后,当我切换到另一个视图时,我会卸载我的dataDictionary以节省内存。在viewDidDissappear中,我把:

  

[dataDictionary release];       数据字典=无;

我还在dealloc中发布了dataDictionary。

然而,似乎存在与mutableCopy相关的内存泄漏,这是我制作的唯一mutableCopy,因此它必须来自上面显示的mutableCopy。有没有人知道为什么这可能会泄漏?我认为mutableCopy除了为NSMutableDictionary做的分配之外还做了另一个分配,但是我不知道如何处理它,因为mutableCopy在字典中并且字典被释放。

提前致谢...

3 个答案:

答案 0 :(得分:4)

mutableCopy方法没有返回一个自动释放的对象,所以你接收了一个保留计数为1的NSMutableData,然后你把它添加到也保留它的字典中 - 这意味着你不会销毁它将它从字典中删除或者当字典被解除分配时,您将丢失对它的任何引用,并且该对象将被泄露。

就像其他人建议的那样,将可变副本添加到dataDictionary时自动释放。

[dataDictionary setObject:[[receivedData mutableCopy] autorelease] forKey:[theConnection description]];

或做类似

的事情
NSMutableData *mutableData = [receivedData mutableCopy];
[dataDictionary setObject:mutableData forKey:[theConnection description]];
[mutableData release];

答案 1 :(得分:1)

尝试这样的事情

[dataDictionary setObject:[[receivedData mutableCopy] autorelease] forKey:[theConnection description]];

答案 2 :(得分:0)

就像Benj和Zaky已经提到的那样,你应该在你的mutableCopy上调用autorelease,但是你还必须确保不在dealloc和viewDidDisappear中释放dataDictionary:由于dataDictionary在创建时保留计数为1,并且viewDidDisappear: dealloc可能在视图被销毁时被调用,因此您最终会尝试释放已经被释放的对象。

确保只在dealloc中发布dataDictionary,您将看不到您提到的“双重免费”错误消息。在viewDidDisappear中调用ivar上的“release”:无论如何都是一个冒险的命题,因为viewDidDisappear:在视图的整个生命周期中被多次调用(例如,如果其他视图控制器被推到你的导航堆栈上)。如果你想确保节省内存,最好在viewDidLoad中创建东西并在viewDidUnload中释放东西。在低内存情况下调用viewDidUnload,所以在这种情况下它正是你想要的。

您可以查看此帖子,了解有关Cocoa引用计数约定的详细说明:Object ownership in stringWithString and initWithString in NSString