【问题标题】:Analyzer issue: Potential leak of an object allocated on line 25 and stored into 'oneCopy'分析器问题:在第 25 行分配并存储到“oneCopy”中的对象的潜在泄漏
【发布时间】:2011-11-09 22:01:44
【问题描述】:

我已经升级了 Xcode,并收到了大量类似这样的分析器警告:

在第 25 行分配并存储到“oneCopy”中的对象的潜在泄漏

谁能指出我正确的方向?

@implementation NSDictionary(DeepMutableCopy)
-(NSMutableDictionary *)mutableDeepCopy
{
    NSMutableDictionary *ret = [[NSMutableDictionary alloc] initWithCapacity:[self count]];
    NSArray *keys = [self allKeys];
    for (id key in keys)
    {
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;

        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [oneValue mutableDeepCopy];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)])
            oneCopy = [oneValue mutableCopy];
        if (oneCopy == nil)
            oneCopy = [oneValue copy];
        [ret setValue:oneCopy forKey:key];
    }
    return ret;
}
@end

显示行号的屏幕截图:

#import "NSDictionary-DeepMutableCopy.h"


@implementation NSDictionary(DeepMutableCopy)
-(NSMutableDictionary *)mutableDeepCopy
{
    //NSMutableDictionary *ret = [[NSMutableDictionary alloc] initWithCapacity:[self count]];
    NSMutableDictionary *ret = [NSMutableDictionary dictionaryWithCapacity:[self count]];
    NSArray *keys = [self allKeys];
    for (id key in keys)
    {
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;

        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [oneValue mutableDeepCopy];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)])
            oneCopy = [oneValue mutableCopy];
        if (oneCopy == nil)
            oneCopy = [oneValue copy];
        [ret setValue:oneCopy forKey:key];
        [oneCopy release];
    }
    return ret;

}
@end

【问题讨论】:

  • 你能告诉我们哪一行是第 25 行吗?
  • 查看编辑,我还遇到了另一个错误。

标签: objective-c xcode cocoa-touch analyzer


【解决方案1】:

首先解决您的第二个问题,而不是[[NSMutableDictionary alloc] initWithCapacity:[self count]],您可以使用[NSMutableDictionary dictionaryWithCapacity:[self count]],它将返回一个自动释放的对象,您必须自己在调用代码中保留它。

另一方面,如果您希望方法返回一个保留的对象而不抛出错误,您可以重命名您的方法以以单词 copy 开头 - 我认为这正是您在这种情况下想要做的。我的其余回复假设您已经选择了这条路。

我最初的回答如下:您不会在每次迭代结束时发布 oneCopy。尝试在[ret setValue:oneCopy forKey:key]; 之后添加[oneCopy release];

然而,Alexsander Akers points out 编译器认为 -mutableDeepCopy 的引用计数为 0。因此,如果您按照上面的建议重命名并包含 [oneCopy release],就像我最初建议的那样,它应该同时处理这两个问题。如果没有,请务必查看他引用的问题中的其他一些解决方案。

例子:

@implementation NSDictionary(DeepMutableCopy)
-(NSMutableDictionary *)copyWithDeepCopiedValues
{
    NSMutableDictionary *ret = [[NSMutableDictionary alloc] initWithCapacity:[self count]];

    NSArray *keys = [self allKeys];
    for (id key in keys)
    {
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;

        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [oneValue copyWithDeepCopiedValues];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)])
            oneCopy = [oneValue mutableCopy];
        if (oneCopy == nil)
            oneCopy = [oneValue copy];
        [ret setObject:oneCopy forKey:key];

        [oneCopy release];
    }

    return ret;
}
@end

【讨论】:

  • 它不喜欢那样...我现在在新线路上收到Incorrect decrement of the reference count of an object that is not owned at this point by the caller.. 还有其他想法吗?
  • @Jules 我更新了我的答案以反映您提供的其他信息。
  • @Dave,我仍然收到Incorrect decrement of the reference count of an object that is not owned at this point by the caller 参见上面的编辑
  • @Jules 抱歉,我可能会因为提到 autorelease 方法而感到困惑。因为在您的情况下,您(大概)确实想要返回一个保留的对象,我的回答的第二部分假设您继续保留该对象并简单地更改您的方法名称。
【解决方案2】:

这里有两个问题。首先,正如@David Brainer-Banker 所说,您需要在每次迭代结束时通过放置 [oneCopy release]; after you set[ret setValue:oneCopy forKey:key];` 来释放 oneCopy

不正确的引用计数递减是第二个问题。这是因为oneCopy 对象可能具有+10 引用计数。 -copy-mutableCopy 返回的对象有一个+1 引用计数,但-deepMutableCopy 返回的对象有一个0 引用计数,因为它不在newcopy 或@987654334 中@(等)家庭。

这个问题与this one 完全相同,并且有一些很好的回答。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    相关资源
    最近更新 更多