【问题标题】:What's the recommended approach for allocating an object in an instance methode, which will later on be returned?在实例方法中分配对象的推荐方法是什么,稍后将返回?
【发布时间】:2011-06-20 08:20:54
【问题描述】:

例如看下面的例子:

代码1

-(NSString*)getString{
    return [[[NSString alloc] initWithFormat:@"test"] autorelease];
}

-(void)printTestString{
    NSString *testStr = self.getString;
    [testStr retain]
    NSLog(@"%@",testStr);
    [testStr release]
}

代码2

-(NSString*)getString{
    return [[NSString alloc] initWithFormat:@"test"];
}

-(void)printTestString{
    NSString *testStr = self.getString;
    NSLog(@"%@",testStr);
[testStr release];
}

代码 1 和代码 2 应该是有效的代码片段,并且不应出现泄漏。

代码 1 使用自动释放,因此返回变量必须保留在 printTestString 中,并在使用后释放。所以这里有一个小的开销,因为自动释放。

代码 2 不会在 getString 中释放 NSString,因此您只需在使用后释放它。似乎你必须少写,而且你没有开销,因为没有使用自动释放。

哪一种是实际使用的“标准”方法?

我问自己的另一件事。 getString 中的自动释放和保留与

[testStr retain]

是个问题,当自动释放池在释放变量之后

NSString *testStr = self.getString;

那么字符串就会消失。这是可能的还是编译器阻止了这种事情?

谢谢

-赛博

【问题讨论】:

  • @MusiGenesis 这是我推荐的方法:如果您不喜欢 Obj-C,请不要在其中编程,也不要回答人们的 Obj-C 问题。

标签: iphone objective-c memory-management


【解决方案1】:

这样做:

-(NSString*)getString{
    return [[[NSString alloc] initWithFormat:@"test"] autorelease];
}

-(void)printTestString{
    NSString *testStr = self.getString;
    NSLog(@"%@",testStr);
}

您的 getString 方法会自动释放 NSString,这意味着 printTestString 不需要保留或释放它。 getString 中的自动释放是有意义的,因为它分配了对象,因此是对象的“所有者”。我建议在继续之前研究 Objective-C 的内存管理规则,因为它们非常重要。

http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH

【讨论】:

  • 好的,但我仍然必须使用自动释放。我希望我可以通过不使用它来解决它。看来我必须。我真的很喜欢它,因为我的代码尽可能高效。
  • 你不必这样做,但是当你有一个创建和返回对象的方法时,你应该这样做。当他们的代码尽可能高效时,每个人都喜欢它。调用 autorelease 只是将它添加到您没有创建的已经存在的池中(除非您这样做了)。当该池耗尽时,您的对象会收到一条释放消息。这是唯一的开销,真的没什么大不了的。
  • 好的,JakeVA,谢谢。我确信并坚持使用自动释放。
  • @sebo 很高兴听到。您能否将此标记为您问题的答案?
【解决方案2】:

Jake 的回答对于您需要从方法返回对象的几乎所有情况都是正确的,但在某些情况下您可能希望返回未自动释放的内容。来自Memory Management Programming Guide(Mac 版,但规则相同):

如果你拥有一个对象的所有权 使用其名称的方法创建它 以“alloc”或“new”或 包含“copy”(例如,alloc, newObject 或 mutableCopy),或者如果您 向它发送一条保留消息。

另外,来自Coding Guidelines for Cocoa

在你的方法和函数中 返回对象值,请确保 你返回这些值自动释放 除非它们是对象创建或 对象复制方法(new、alloc、copy 及其变体)。 “自动发布”在 这种情况并不一定意味着 对象必须是明确的 自动释放——即发送 自动释放到之前的对象 退回它。在一般意义上,它 只是意味着返回值不是 被调用者释放。

出于性能原因,它是 建议避免自动释放 方法实现中的对象 尽可能,尤其是代码 可能会经常执行 短时间内;一个例子 这样的代码将是一个未知的循环 并且可能有很高的循环次数。

因此,包含前缀 allocnew 的方法,或者按照惯例包含单词 copy 的方法将返回非自动释放的对象。事实上,Clang 静态分析器理解这个约定,并假定从遵循这些命名规则的方法返回的非自动释放对象。

在我不想返回自动释放对象的情况下(我不想管理自动释放池的紧密循环等),我使用了new 前缀。同样,几乎在所有情况下都建议返回自动释放的对象,但有时您可能希望避免这种情况。

【讨论】:

    猜你喜欢
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多