初始化方法和“带有+0保留计数的对象返回给调用者,其中+1(拥有)保留计数是预期的” - 误报?
首先: 我明白了,为什么这个警告是存在的,我只是无法解释自己,为什么在这种情况下触发它。 官方Cocoa内存管理策略如下: “您拥有您创建的任何对象 您可以使用名称以”alloc“,”new“,”copy“或”mutableCopy“开头的方法创建对象(例如。,分配,NEWOBJECT,或mutableCopy)初始化方法和“带有+0保留计数的对象返回给调用者,其中+1(拥有)保留计数是预期的” - 误报?
您可以使用保留”
我知道有这样的代码的对象的所有权:
- (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
}
据我所知,这是从铛假阳性,不是吗? 我的意思是,增加保留计数的唯一方法是“保留”和名称以“alloc”,“new”,“copy”或“mutableCopy”开头的所有方法,所以“init”不是增加保留计数,但在调用者上继续传递类“alloc” - 方法的返回值,所以实际上“init”预计会返回+0保留计数,而不是+1,不是吗?它只是返回具有相同保留计数的对象,并已传入该对象。 现在对该对象调用“foo”也不会更改保留计数,因此此代码应完全合法,实际上它工作正常并且在程序的整个生命周期内保留计数是正确的,只有静态分析仪在抱怨。
按照惯例方法名foo
意味着它返回一个调用者不拥有的对象。
alloc
- init***
组合返回调用者拥有的对象。
看起来像分析仪不能或不想看看foo
看看它实际在做什么,并不知道返回的值是与已有的self
相同的对象。
这不是假阳性。如果一个子类,或者动态加载的类重写foo的返回别的东西:
- (id) foo; {
return [NSNumber numberWithInt:666];
}
,那么你将有self
泄漏和NSNumber
对象的过度释放。
是的,这是一个误报,但在设计课程时这是一个不好的做法。 相反,你应该调用foo,然后回归自我,就像这样:
-(id) init
{
if ((self = [super init]))
{
[self foo];
}
return self;
}
据我所知富按照惯例只是意味着,它不会改变保留计数,同样喜欢初始化。约定在哪里陈述了关于必须在那里返回一个自动释放对象的事情? – Kaiserludi 2012-03-26 16:13:20
@Kaiserludi它指定你是否拥有一个对象。你将一个你拥有的对象替换为另一个你不拥有的对象,除非它们是同一个对象,并且由于动态代码加载,否则在所有情况下显然都是错误的,你不能确定它永远是案子。对我来说似乎完全合理的行为。 – hamstergene 2012-03-26 17:14:01
@Kaiserludi事实上,这里有两个问题:其一,你返回一个方法的标记结果(通过约定)返回一个非拥有对象(即返回[self foo])。这是编译器抱怨的错误。二,你从init方法中返回除self之外的东西,而不释放自己(即你正在泄漏自己)。foo写的方式,这两个错误(一个过度释放和一个泄漏)恰好相互抵消。 – jfortmann 2012-03-26 17:37:48