我正在运行 Leaks 工具,发现我的 Dictionary mutableDeepCopy 中存在大量泄漏,但我无法弄清楚代码出了什么问题。有什么建议吗?
@interface RootViewController : UIViewController{
NSDictionary *immutableDictionary;
NSMutableDictionary *mutableDictionary;
}
这是在 Instruments 中突出显示的代码行
self.mutableDictionary = [self.immutableDictionary mutableDeepCopy];
这是创建字典的可变副本的方法
@interface NSDictionary(MutableDeepCopy)
-(NSMutableDictionary *)mutableDeepCopy;
@end
这是方法实现,我突出显示了 Leaks 所说的 100% 泄漏的代码
- (NSMutableDictionary *) mutableDeepCopy {
NSMutableDictionary *dictionaryToReturn = [NSMutableDictionary dictionaryWithCapacity:[self count]];
NSArray *keys = [self allKeys];
for(id key in keys) {
id value = [self valueForKey:key];
id copy = nil;
if ([value respondsToSelector:@selector(mutableDeepCopy)]) {
copy = [value mutableDeepCopy];
} else if ([value respondsToSelector:@selector(mutableCopy)]) {
copy = [value mutableCopy]; //This is the Leak
}
if (copy == nil) {
copy = [value copy];
}
[dictionaryToReturn setValue:copy forKey:key];
}
return dictionaryToReturn;
}
最佳答案
您需要根据 Apple 的 Memory Management Rules 来分析这一点.
从这一行开始:
self.mutableDictionary = [self.immutableDictionary mutableDeepCopy];
我希望 mutableDeepCopy 返回一个我拥有的对象,所以在某些时候我需要释放或自动释放它。例如
NSMutableDeepCopy* temp = [self.immutableDictionary mutableDeepCopy];
self.mutableDictionary = temp;
[temp release];
或
self.mutableDictionary = [[self.immutableDictionary mutableDeepCopy] autorelease];
所以现在我们需要看看 mutableDeepCopy。因为它的名称中有“copy”,所以它需要返回一个“拥有的”对象,这实际上意味着“忘记”释放返回的对象。当您在第一行中创建返回的对象时,您已经无法做到这一点,因为 DictionaryWithCapacity: 为您提供了一个不属于您的对象。将其替换为
NSMutableDictionary *dictionaryToReturn = [[NSMutableDictionary alloc] initWithCapacity:[self count]];
现在你拥有它了。
让 mutableDeepCopy 遵守规则非常重要,因为这意味着您可以以完全相同的方式处理从 mutableDeepCopy、mutableCopy 和 copy 返回的对象。在所有三种情况下,您都拥有插入到数组中的对象副本。因为你拥有它,所以你必须释放它,否则它就会像你发现的那样泄漏。因此,在循环结束时,您需要
[copy release];
这将阻止泄漏。
关于iphone - 无法弄清楚如何修复 iPhone 上的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4361231/