我正在运行Leaks工具并在我的Dictionary mutableDeepCopy中发现了大量泄漏,但我无法弄清楚代码有什么问题。有什么建议吗?
@interface RootViewController : UIViewController{
NSDictionary *immutableDictionary;
NSMutableDictionary *mutableDictionary;
}
以下是在Instruments
中突出显示的代码行self.mutableDictionary = [self.immutableDictionary mutableDeepCopy];
以下是创建Dictionary的可变副本的方法
@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;
}
答案 0 :(得分:3)
您的财产如何申报?如果是retain
或copy
,那么这不会泄漏。
你的问题是名称mutableDeepCopy
表明它返回一个保留对象,而不是实际发生的自动释放对象。
修改强>
在mutableDeepCopy本身,你需要在添加到字典后释放copy
变量。
答案 1 :(得分:3)
您需要根据Apple的Memory Management Rules进行分析。
从这一行开始:
self.mutableDictionary = [self.immutableDictionary mutableDeepCopy];
我希望mutableDeepCopy返回我拥有的对象,所以在某些时候我需要释放或自动释放它。 e.g。
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 release];
那会阻止泄漏。
答案 2 :(得分:2)
mutableCopy
增加对象的保留计数,setValue:forKey:
也是如此。这意味着当dictionaryToReturn
被解除分类时,调用mutableCopy
的对象的保留计数为一。
尝试这样做:
copy = [[value mutableCopy] autorelease];