无法弄清楚如何修复 iPhone 上的内存泄漏
我正在运行 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;
}
I was running Leaks tool and discovered a massive leak in my Dictionary mutableDeepCopy but I can't figure out what's wrong with the code. Any suggestions?
@interface RootViewController : UIViewController{
NSDictionary *immutableDictionary;
NSMutableDictionary *mutableDictionary;
}
Here is the line of code that's highlighted in Instruments
self.mutableDictionary = [self.immutableDictionary mutableDeepCopy];
Here is the method for creating a mutable copy of a Dictionary
@interface NSDictionary(MutableDeepCopy)
-(NSMutableDictionary *)mutableDeepCopy;
@end
Here is method implementation, I've highlighted the code that Leaks saids is leaking 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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要根据Apple的内存来分析这一点管理规则。
从这一行开始:
我希望 mutableDeepCopy 返回我拥有的对象,因此在某些时候我需要释放或自动释放它。例如
或
所以现在我们需要看看 mutableDeepCopy。因为它的名称中有“copy”,所以它需要返回一个“拥有的”对象,这实际上意味着“忘记”释放返回的对象。当您在第一行中创建返回的对象时,您已经无法做到这一点,因为 DictionaryWithCapacity: 为您提供了一个您不拥有的对象。将其替换为“
现在您拥有它”。
让 mutableDeepCopy 遵守规则非常重要,因为这意味着您可以以完全相同的方式处理从 mutableDeepCopy、mutableCopy 和 copy 返回的对象。在所有三种情况下,您都拥有插入到数组中的对象副本。因为你拥有它,所以你必须释放它,否则它就会像你发现的那样泄漏。因此,在循环结束时,您需要
阻止泄漏。
You need to analyse this in light of Apple's Memory Management Rules.
Starting with this line:
I would expect mutableDeepCopy to return an object I own, so at some point I need to release or autorelease it. e.g.
or
So now we need to look at mutableDeepCopy. Because it has 'copy' in the name it needs to returned an "owned" object which, in practice means "forgetting" to release the returned object. You have already failed to do that when you create the returned object in the first line, since dictionaryWithCapacity: gives you an object you do not own. Replace it with
Now you own it.
It is important that you make your mutableDeepCopy obey the rules because it means you can treat the objects returned from mutableDeepCopy, mutableCopy and copy in exactly the same way. In all three cases you own the object copy that you insert into the array. Because you own it, you must release it or it'll leak as you found out. So, at the end of the loop, you need
That'll stop the leak.
您的财产如何申报?如果是
retain
或copy
,那么这不会泄漏。您的问题是,名称
mutableDeepCopy
表明它返回一个保留的对象,而不是实际返回的自动释放的对象。编辑:
而在 mutableDeepCopy 本身,您需要在添加到字典后释放
copy
变量。How is your property declared? If is is
retain
orcopy
, then this doesn't leak.Your problem is that the name
mutableDeepCopy
suggests that it returns a retained object, and not an autoreleased one as it actually does.Edit:
And at the mutableDeepCopy itself, you need to release the
copy
variable after adding to the dictionary.mutableCopy
会增加对象的保留计数,setValue:forKey:
也是如此。这意味着当dictionaryToReturn
被释放时,调用了mutableCopy
的对象的保留计数仍然为 1。尝试这样做:
mutableCopy
increments the retain count of the object, as doessetValue:forKey:
. This means that whendictionaryToReturn
is dealloc'ed, the object that hadmutableCopy
called still has a retain count of one.Try doing this instead: