【问题标题】:Objective C Naming Convention for an object that owns itself拥有自己的对象的Objective C命名约定
【发布时间】:2011-02-18 18:07:57
【问题描述】:

使用包含静态分析器的最新版本的 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];
}

对象拥有自己,完成后会释放自己,但没有存储它的地方,因此静态分析器将其视为某处的泄漏。是否有一些命名或编码约定可以提供帮助?

【问题讨论】:

  • 在 newFoo 中它真的返回 foo 而不是 myFoo 吗?

标签: objective-c cocoa-touch xcode


【解决方案1】:

在您的newFoo 实现中,您创建并返回一个逻辑保留计数为+1 的Foo 实例。 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;
}

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

【讨论】:

  • 上面的代码是一个例子,但还有一些更难处理的代码。例如,一个等待 UIButton 被点击并在处理完点击后释放自己。由于 UIButton 不保留目标,它必须保留自己。有什么想法吗?
  • 接受部分回答;仍在寻找更好的解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-19
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多