init方法和"具有+0保留计数的对象返回给调用者,其中预期+1(拥有)保留计数" - 假阳性?

时间:2012-03-26 15:03:02

标签: objective-c clang-static-analyzer

首先: 我明白,为什么这个警告存在,我无法解释自己,为什么在这种情况下会触发它。 官方Cocoa内存管理策略如下: “你拥有你创建的任何对象 使用名称以“alloc”,“new”,“copy”或“mutableCopy”开头的方法(例如,alloc,newObject或mutableCopy)创建对象。

您可以使用retain“

获取对象的所有权

我知道有这样的代码:

- (id) foo
{
    // do something
    return self;
}

- (id) init
{
    self = [super init];
    return [self foo]; // clang static analyzer is complaining about returning an object with a +0 retain count here, although a +1 would be expected
}

Afaik这是来自铿锵的假阳性,不是吗? 我的意思是,增加保留计数的唯一方法是“保留”和所有方法,其名称以“alloc”,“new”,“copy”或“mutableCopy”开头,因此“init”不会增加retain-count,但调用者的中继,传递类“alloc”方法的返回值,所以实际上“init”预计返回+0保留计数,而不是+1保持计数,isn是吗?它只返回具有相同保留计数的对象,并将其传入。 现在在该对象上调用“foo”也不会改变保留计数,所以这段代码应该是完全合法的,事实上它的工作正常并且保留计数在整个程序的整个生命周期都是正确的,只有静态分析器抱怨。

2 个答案:

答案 0 :(得分:4)

按照约定,方法名称foo表示它返回调用者不拥有的对象。

alloc - init***组合返回调用者拥有的对象。

看起来分析器不能或者懒得查看foo内部以查看它实际在做什么,并且不知道返回的值是与已拥有的{{1}相同的对象}。

这不是误报。如果子类或动态加载的类别覆盖foo以返回其他内容:

self

然后你会发现- (id) foo; { return [NSNumber numberWithInt:666]; } 的泄漏和self对象的过度释放。

答案 1 :(得分:-1)

是的,这是假阳性,但在设计课程时使用这是一种不好的做法。 相反,你应该调用foo,然后返回self,就像这样:

-(id) init
{
    if ((self = [super init]))
    {
        [self foo];
    }

    return self;
}