【问题标题】:Releasing objects returned by method释放方法返回的对象
【发布时间】:2025-12-04 05:45:02
【问题描述】:

好的,我知道这个问题的答案应该很明显,但我需要朝着正确的方向努力。

我发现自己编写了大量遵循以下模式的方法:

-(NSThing*)myMethod{

  NSThing *thing = [[NSthing alloc] init];
  // do some stuff with the thing
  return thing;
}

我的问题是,我该如何处理这个对象的释放?显然我不能在方法中释放它。

【问题讨论】:

    标签: objective-c memory-management autorelease


    【解决方案1】:

    通常你会自动释放它

    -(NSThing*)myMethod{
    
      NSThing *thing = [[NSthing alloc] init];
      // do some stuff with the thing
      return [thing autorelease];
    }
    

    【讨论】:

    • 嗨,我可以在这里做 {NSThing *thing = [[[NSthing alloc] init] autorelease];return thing;} 吗?
    【解决方案2】:

    正如 newacct 所说,自动释放是摆脱这种情况的简单方法。但是,您应该考虑要返回的对象的“所有权”。

    在 Objective-C 中,一般的经验法则是,任何名称中带有 allocnewcopy 的方法都会返回一个不会自动释放的对象,而其他方法(如类方法)会在-autorelease 要返回的对象。所以这三个在自动释放方面是不等价的(尽管编译器可能会做一些魔术并将它们全部简化为字符串常量):

    // Autoreleased
    NSString *string1 = [NSString stringWithString:@"aString"];
    NSString *string2 = [[[NSString alloc] initWithString:@"aString"] autorelease];
    
    // NOT autoreleased
    NSString *string3 = [[NSString alloc] initWithString:@"aString"];

    您的代码可以采用类似的方法,您可以考虑谁拥有您要返回的对象。在您提供的具体示例中,方法是 allocing 和 initing 对象,因此通常您在自己的方法中负责 autoreleaseing [原文如此]。但是,如果您要编写一个采用预先存在的对象并以某种方式对其进行修改的方法,您将不会拥有该对象,也不会负责自动释放返回的对象。 (当对象所属的自动释放池耗尽时,这样做实际上可能会导致问题。)

    另请参阅(感谢 cmets 中的 Peter 和 Quinn!):

    【讨论】:

    • 从技术上讲,应该是任何以“alloc”或“new”开头或包含“copy”而不是“init”的方法,虽然alloc后面必然跟着init,但并不是所有init都跟着alloc .见 developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/…>
    • 在 cmets 中,将 放在链接周围会导致 URL 末尾出现额外的转义字符。这是没有尖括号的相同 URL:developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/…
    • 如果参数是文字字符串,+stringWithString: 通常会减少,但对于 +stringWithFormat: 则不能这样做——该方法保证返回不同的 NSString 实例。