2011-10-03 35 views
0

我认为我理解保留/释放在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'? 

我随机场合看到的是,视图有时会显示“姓名”字段为空时,它填充表从另一种观点回来后。这可能是另一个问题,但我想确定我使用'autorelease'。

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

或者,我是否必须在中介方法中调用'retain'?我在想'autorelease'可能会在方法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],因为它是一个autorelated对象,我可以简单地返回“player”并使用它?感谢您的回应!

+0

静态分析是有帮助你! – justin

+1

我会检查一下Justin的发言。谢谢! – Christopher

+1

静态分析仪非常漂亮!我不知道为什么我没有使用它。我确实使用了检漏仪。在这工作。 – Christopher

回答

2

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

答案是肯定的。

或者,我是否必须在中介方法中调用'retain'?

是否要调用retain取决于您的方法的语义。在Obj-C/Cocoa中,以下约定适用:名称以“alloc”或“new”开头或包含“copy”的方法将返回一个retained对象;否则您可能会得到一个autoreleased对象,那么根据其需要保留它是主叫方的责任。

我在想'autorelease'可能会在方法getPlayerNameByIndex中释放。

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

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

+0

返回的对象可能会也可能不会被自动释放;它根本不是由调用者拥有的。它仍然可以由另一个对象拥有。所有权和在autorelease池是不一样的。 –

+0

@Josh Caswell:我的回答中是否使用过“所有权”一词?我错过了一些东西......--) – sergio

+0

对不起,我指的是你的句子“......否则你可能会得到一个'autorelease'd对象”,这不太准确,因为对象的autorelease游泳池是未知的,我相信,这是错误的想法。 –

2

getPlayerNameByIndex线:

[player release]; 

是黄,移除它。你没有获得所有权。通过调用带有alloc的方法获得所有权,或者方法名以新的,复制或明确的保留开始。 (NARC)。

您不需要释放玩家,因为您没有获得所有权,请参阅上述规则。

getPlayerName: 可以简化为:

return player.nickname; 

方法名可以简化为:

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

不是他所问的,我想,但是好点!原始海报:参见塞尔吉奥关于新/分配/复制规则的描述;你用来获得玩家的工厂方法并不是新的,分配或复制,所以你不拥有该参考。 – Tommy