2010-05-12 41 views
3

使用包含静态分析器的最新XCode版本时,我的一些对象正在抛出分析器问题报告。具体来说,我有一个拥有自己的对象,负责释放自己,但也应该返回给调用者,并可能手动保留。Objective C命名约定为拥有自己的对象

如果我有一个像+ (Foo) newFoo这样的方法,分析器会看到单词New,并在调用者中报告问题newFoo预计会返回一个保留为+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

in newFoo它真的会返回foo而不是myFoo吗? – Mark 2010-05-12 17:26:23

+0

让我解决这个问题 – 2010-05-12 17:27:39

回答

2

在您实施newFoo时,您创建并返回逻辑保留数为+1的Foo实例。可可Memory Management Rules要求以new作为前缀的方法必须返回一个保留的对象。但他们也表示对象所有权被传递给调用方法。这意味着,你不能在后台线程上释放对象。

我提议让我们更清晰和更可可十岁上下的方式:

重命名newFoo喜欢的东西fooInBackground(其中foo应该是一个动词)。这个新方法返回一个autoreleased实例,让线程完成它自己的所有权。 performSelectorInBackground:withObject:保留了接收者和对象参数,所以没有理由保留它,并手动在后台方法中释放它。

+ (Foo *) fooInBackground { 
    Foo *myFoo = [[[Foo alloc] init] autorelease]; 
    [myFoo performSelectorInBackground:@selector(bar) withObject:nil]; 
    return myFoo; 
} 

旁注:自您fooInBackground返回myFoo对象这将是刚刚发布,而不是返回之前自动释放对象的错误。后台线程可以在第一个线程有机会在调用方法中保留myFoo之前完成。我只是这么说的,因为似乎有一个(无根据的)对所有新的iPhone程序员来到Cocoa的自动释放的专注。

+0

上面的代码就是一个例子,但还有其他的代码更难处理。例如,一个人等待UIButton被点击并在完成处理点击后自行释放。由于UIButton不保留目标,它必须保留自己。那里有任何想法? – 2010-05-12 18:21:40

+0

接受部分回答;仍在寻找更好的解决方案 – 2010-06-04 14:59:21