【问题标题】:Retain/Release through intermediary method通过中介方式保留/释放
【发布时间】:2011-10-03 16:21:29
【问题描述】:

我想我大部分都了解 Objective-C 中的保留/释放。但是,我有一个我不确定的具体案例。这是一个例子:

+ (NSString *)getPlayerNameByIndex:(NSInteger)globalIndex:(ABAddressBookRef)addressBook
{
    ...
    Player *player = [PlayerHelper loadPlayer:globalIndex];
    NSString *name = [PlayerHelper getPlayerName:player :addressBook];
    [player release];

    // 'retain' here?    
    return name;
}

+ (NSString *)getPlayerName:(Player *)player:(ABAddressBookRef)addressBook
{
    ...
    NSString *name = [[[NSString alloc] initWithString:player.nickname] autorelease];
    return name;
}

所以我打电话给...

NSString *name = [PlayerHelper getPlayerNameByIndex:index:addressBook];
// name is 'autorelease'?

我在随机场合看到的是,视图有时会在从另一个视图返回后填充表格时将“名称”字段显示为空。这可能是另一个问题,但我想确定我使用了“自动释放”。

我的问题的核心是在 getPlayerName 中使用“自动释放”。 'autorelease' 状态是否通过 getPlayerNameByIndex 方法传递给调用者?

或者,我必须在中间方法中调用“保留”吗?我在想“自动释放”可能会在 getPlayerNameByIndex 方法中释放。

希望我的问题很清楚。任何帮助表示赞赏。

更新:更多信息以供澄清......

NSError *error = nil;
Player *player = nil;
NSArray *array = [appDelegate.managedObjectContext executeFetchRequest:request error:&error];
if ([array count] == 1)
{
    player = [array objectAtIndex:0];
    [player retain];
}

这本质上是从核心数据加载信息的“loadPlayer”方法。从答案听起来我不需要调用[player retain],因为它是一个自动相关的对象,我可以简单地返回“player”并使用它?感谢您的回复!

【问题讨论】:

  • 静态分析器为您提供帮助!
  • 我会马上去看看贾斯汀..谢谢!
  • 静态分析器很漂亮!我不知道为什么我没有使用它。我确实使用泄漏检查器。正在处理这个问题。
  • 是的,它可以快速指出编译器可能遗漏的很多问题,并为您节省大量时间。

标签: objective-c autorelease


【解决方案1】:

我的问题的核心是在 getPlayerName 中使用“自动释放”。 'autorelease' 状态是否通过 getPlayerNameByIndex 方法传递给调用者?

答案是肯定的。

或者,我必须在中间方法中调用'retain'吗?

是否要调用 retain 取决于方法的语义。

在 Obj-C/Cocoa 中,适用以下约定:名称以“alloc”或“new”开头或包含“copy”的方法将返回 retained 对象;否则你可以期望得到一个autoreleased 对象,那么调用者有责任根据需要保留它。

我在想“自动释放”可能会在 getPlayerNameByIndex 方法中释放。

自动释放的对象在自动释放池耗尽的下一个时间点被释放;这通常与返回主循环有关(尽管没有关于此的详细信息);所以你可以很确定自动释放不会在getPlayerNameByIndex...

希望这有助于澄清问题...

【讨论】:

  • 返回的对象可能会也可能不会自动释放;它根本不属于调用者。它仍然可以由另一个对象拥有。所有权和在自动释放池中不是一回事。
  • @Josh Caswell:我在回答中是否使用了“所有权”这个词?我错过了一些东西...... :-)
  • 对不起,我指的是你的句子“......否则你可以期望得到一个autoreleased 对象”,这不太准确,因为该对象在自动释放池中的成员身份未知,而且我认为这是错误的想法。
【解决方案2】:

getPlayerNameByIndex行:

[player release];

是wong,删除它。您没有获得所有权。通过使用 alloc 调用方法或方法名称以 new、copy 或显式保留开头来获得所有权。 (NARC)。

你不需要释放播放器,因为你没有获得所有权,见上面的规则。

getPlayerName: 可以简化为:

return player.nickname;

方法名可以简化为:

+ (NSString *)getPlayerName:(Player *)player

【讨论】:

  • 我认为不是他要问的,而是好地方!致发帖人:见 sergio 对 new/alloc/copy 规则的描述;您用于获取播放器的工厂方法不是新的、分配或复制的,因此您不拥有该引用。
猜你喜欢
  • 2010-12-02
  • 1970-01-01
  • 2011-01-24
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 1970-01-01
相关资源
最近更新 更多