随着最新版本的XCode包含静态分析器,我的一些对象正在抛出报告分析器问题。具体来说,我有一个拥有自己的对象,负责释放自己,但也应该返回给调用者并可能手动保留在那里。
如果我有像+ (Foo) newFoo
这样的方法,分析器会看到单词New并在调用者中报告一个问题,即newFoo
应该返回一个带有retain +1的对象,而不是在任何地方发布。如果我将其命名为+ (Foo) getFoo
,分析器会报告该方法中的问题,说明存在潜在的泄漏,因为它在返回之前未被解除分配。
我的班级基本上是这样的:
+ (Foo *) newFoo {
Foo *myFoo = [[[Foo new] retain] autorelease];
[myFoo performSelectorInBackground:@selector(bar) withObject:nil];
return myFoo;
}
- (void) bar {
//Do something that might take awhile
[self release];
}
对象拥有自己,当它完成时,它将自行释放,但是它没有存储它,因此静态分析器将其视为某处的泄漏。是否有一些命名或编码约定可以帮助?
答案 0 :(得分:2)
在newFoo
的实现中,您创建并返回一个Foo
实例,其逻辑保留计数为+1。 Cocoa Memory Management Rules要求前缀为new
的方法必须返回一个保留对象。但他们还声明对象所有权传递给调用方法。这意味着,您无法在后台线程上释放该对象。
让我提出一个更清晰,更可靠的方式:
将newFoo
重命名为fooInBackground
(其中foo应为动词)。这个新方法返回一个自动释放的实例,让线程执行它自己的所有权。 performSelectorInBackground:withObject:
保留接收者和对象参数,因此没有理由保留它,否则在后台方法中手动释放它。
+ (Foo *) fooInBackground {
Foo *myFoo = [[[Foo alloc] init] autorelease];
[myFoo performSelectorInBackground:@selector(bar) withObject:nil];
return myFoo;
}
旁注:由于您从myFoo
返回fooInBackground
对象,因此在返回之前释放对象而不是自动释放对象将是一个错误。后台线程可以在第一个线程有机会在调用方法中保留myFoo
之前完成。我只是这样说,因为似乎存在一种(毫无根据的)对自动释放的关注,所有新的iPhone程序员都来到Cocoa。