2011-10-03 39 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