1

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

您可以使用保留“获取对象的所有权”

我知道有这样的代码:

- (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 这是来自 clang 的误报,不是吗?我的意思是,增加保留计数的唯一方法是“保留”以及名称以“alloc”、“new”、“copy”或“mutableCopy”开头的所有方法,因此“init”不会增加保留计数,但在调用者上传递,以传递类的“分配”方法的返回值,所以实际上“init”应该返回一个+0保留计数,而不是一个+1,是不是吗?它只是返回具有相同保留计数的对象,它已被传入。现在在该对象上调用“foo”也不会更改保留计数,因此这段代码应该是完全合法的,实际上它工作得很好,并且保留计数在程序的整个生命周期内都是正确的,

4

2 回答 2

4

按照惯例,方法名称foo意味着它返回调用者不拥有的对象。

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

看起来分析器不能或懒得去看看foo它实际上在做什么,并且不知道返回的值与已经拥有的对象是同一个对象self

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

- (id) foo; {
    return [NSNumber numberWithInt:666];
}

那么你将有一个对象的泄漏self和过度释放NSNumber

于 2012-03-26T15:08:23.803 回答
-1

是的,这是一个误报,但在设计类时这是一个不好的做法。相反,您应该调用 foo,然后返回 self,如下所示:

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

    return self;
}
于 2012-03-26T15:09:03.803 回答