2010-02-17 52 views
7

我是新來的目標c,並試圖瞭解如何/何時autorelease被稱爲。我理解的簡單的例子:這個未來情況返回autorelease目標c中的錯誤?

- (void) foo { 
    Bar *b = [[[Bar alloc] init] autorelease]; 
    [self doSomething:b]; 
    } 

什麼 - 這是一個錯誤,因爲該對象將在離開makeBar的範圍立即釋放?

-(Bar*) makeBar 
{ 
    return [[[Bar alloc] init] autorelease]; 
} 

如果調用者做了保留怎麼辦?

Bar *b = [[self makeBar] retain]; 

感謝, -Eric

+1

這個問題的內容和下面的兩個答案應該在ObjC – ckhan

回答

7

在你的第二個例子,您傳回匿名對象將不盡快執行葉makeBar但在運行的下一次迭代的範圍公佈循環。這將使你在任何方法的機會,retain它稱爲makeBar

所以,你的最後一個例子是確定的,因爲保留計數不會低於0

你用起來麻煩嗎?

+1

的新增內容的必讀列表上。更具體的說,當它被添加到的自動釋放池被排空/釋放時,它將被釋放。這通常是在運行循環結束時,但並非總是如此。 – dreamlax

+0

沒有問題,我剛剛掃描我的代碼以查找潛在的內存問題,並從我已複製的示例代碼中看到該模式,並且不確定它是否爲錯誤。 – esilver

5
-(Bar*) makeBar 
{ 
    return [[[Bar alloc] init] autorelease]; 
} 

的第二情況下是返回一個Objective-C的對象優選方式。除了+alloc-copy...-create...,該方法應保留沒有返回對象的所有權,即(的變化)保留計數應爲0。

然而,[[Bar alloc] init]使對象爲具有1 retainCount,一個應在返回之前釋放它。但是-release會立即釋放對象,使得該方法無用。這就是爲什麼使用-autorelease - 這是一個延遲-release,即對象將最終被釋放,但不是現在,所以其他部分的代碼仍然可以與它交互,但保留計數仍可以平衡到0.


Bar *b = [[self makeBar] retain]; 

你應該保留它除非你想成爲的對象b的長期所有者。