【问题标题】:If a function creates and returns an object, should it be in the autorelease pool如果一个函数创建并返回一个对象,它应该在自动释放池中吗
【发布时间】:2011-01-22 20:40:16
【问题描述】:

我对 Objective-c 还是很陌生。

据我所知,我没有从 alloc、new、copy 或 mutableCopy 获得的任何对象都应假定位于自动释放池中。

我假设这也意味着如果我创建一个函数来创建并返回一个对象的新实例,我应该在返回之前将它放在自动释放池中。

例如,我有一个解析xml的函数,并返回一个表示xml中数据的对象,该对象在返回之前应该在自动释放池中。

我主要关心的是 iPhone 的开发,但如果能提供一般性的答案,我们将不胜感激。

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    您可以通过两种方式做到这一点:要么返回调用者拥有的对象,要么返回调用者不拥有的对象(例如,自动释放的对象)。无论您选择哪种策略,都应遵循命名约定。例如,

    - (NSString *)fullNameCopy {
        return [[NSString alloc] initWithFormat:@"%@ %@", self.firstName, self.LastName];
    }
    

    返回调用者拥有的NSString 对象。方法名称为fullNameCopy,遵循命名规则:名称中包含“copy”的方法返回调用者拥有的对象。返回值不放在自动释放池中。

    或者,

    - (NSString *)fullName {
        return [NSString stringWithFormat:@"%@ %@", self.firstName, self.LastName];
    }
    

    - (NSString *)fullName {
        NSString *s = [[NSString alloc] initWithFormat:@"%@ %@", self.firstName, self.LastName];
        return [s autorelease];
    }
    

    返回一个不属于调用者所有的​​字符串,并且方法名不包含 alloc、new 或 copy。返回值是自动释放的,因此当相应的自动释放池耗尽时,它将被释放,除非调用者明确选择保留它。

    也就是说,在您的特定场景中,第二种策略——返回一个不属于调用者的对象——看起来是一个更好的解决方案。调用者很可能会立即处理该对象(因此他不会对拥有该对象感兴趣)或将其保存在属性中(很可能是副本或保留属性)。

    【讨论】:

      【解决方案2】:

      是的,你的权利。如果您在函数中分配了内存,您也有责任释放它。因为您正在返回分配的对象,所以在这种情况下释放它的唯一方法是将其放入自动释放池中,例如

      return [newObject autorelease];
      

      (编辑)

      【讨论】:

      • 你能解释一下如果放在自动释放中你会遇到什么问题吗?我真的看不出问题吗?
      • 其实我认为,Pete 做对了。约定是,任何不以 new、alloc 或 copy 开头的方法都应该返回一个自动释放的对象。如果他想保留它,则此方法的调用者负责保留它。
      • @kubi 我认为你读错了这个问题。他了解如何编写 new、alloc 或 copy 方法。 @Pete 正在询问他的班级实施的其他方法,我的回答是我相信。
      • @boyfarrell,你说得对,我确实错过了。如果您对答案进行编辑,我可以删除我的反对票。
      • @Marco ‘不以 new、alloc 或 copy 开头的方法 [name]’ 有点不正确。 Apple 文档中的措辞是 contain,而不是 start。一个例子是-mutableCopy
      【解决方案3】:
      1. 您应该阅读Objective-C memory management guide
      2. newalloccopy 方法返回的任何对象都是您的。你拥有它,你必须释放它。
      3. 从任何其他方法返回的任何对象都在自动释放池中。如果您想将对象保留在当前范围之外,则必须保留它。

      XML 示例可能是正确的:如果您从一个方法返回一个对象,并且该方法的名称中不包含 newcopy,按照惯例,您应该返回一个自动释放的对象。

      【讨论】:

      • 其实我认为,Pete 做对了。约定是,任何不以 new、alloc 或 copy 开头的方法都应该返回一个自动释放的对象。如果他想保留它,则此方法的调用者负责保留它。
      • 我认为你误读了我的帖子。我认为您错过了“我没有从 alloc 中获得的任何对象”中的“不”。但据我了解,如果我将我的方法命名为“parse”,那么我应该在返回之前调用 autorelease。如果我命名为“newUserFromXml”,那么我不应该这样做?
      • 链接很好,我还没有阅读,但很快就会阅读。
      • 名称不包含 new、alloc 或 copy 的方法返回的对象并不总是自动释放的对象。 Apple 的文档警告不要将它们视为自动释放的对象,因为这是一个有时是正确的实现细节,有时不是。相反,最好将它们视为拥有/不拥有的对象。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-01
      • 2012-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多