2012-05-04 49 views
0

這是一個與Objective-C內存管理有關的問題。Objective-C .mm in initializer and class factory method

About Memory Management頁有一些例子

- (NSString *)fullName { 
    NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@", 
            self.firstName, self.lastName] autorelease]; 
    return string; 
} 

,第二個

- (NSString *)fullName { 
    NSString *string = [NSString stringWithFormat:@"%@ %@", 
            self.firstName, self.lastName]; 
    return string; 
} 

唯一的區別是,在第一實施例的初始化被調用,並且在所述第二類工廠方法。

基本內存管理規則部分是說,在一個alloc調用後,我將擁有我分配的對象。所以在第一個例子中,我分配一個對象並同時初始化它。在這個我自己的對象,並有它release它。在第二個例子中,我沒有。但是工廠方法stringWithFormat:在一次調用中做了同樣的事情,我的意思是分配對象並初始化它?

所以主要問題是,爲什麼我不必在第二個示例中釋放對象? 在實現類工廠方法時是否有任何特殊的內存管理規則?

+0

p.s.所有這些基本上都是隨着ARC的引入而開展的。你可能會更好地閱讀。在ARC下,你簡單地忽略諸如retain,release,autorelease之類的東西(試圖調用這些方法會導致編譯錯誤),並且知道一切都會正常工作。 – ericg

+0

答案基本上是正確的,只是他們聲明從類工廠方法返回的對象是autoreleased。重要的是你不擁有它,沒有權利或責任來釋放它。它可能會或可能不會被自動釋放。可能會有完全不同的內存管理方案。它可能會返回一個單身人士。它可能會返回一個永久性的共享值對象(比如'NSNumber'爲0值數字對象的所有請求保留一個公共實例)。等等 –

回答

2

按照慣例,類工廠方法將返回autorelease池中的對象。它已經爲你完成了alloc,init,autorelease,就像在第一個例子中一樣。除非你保留它,否則當池被排空時,它將被釋放。

+0

那麼按照慣例,一個類工廠方法在執行時還必須執行autorelease嗎? –

+0

是的,它應該。 – ericg

0

你是對的,工廠方法在內部調用alloc,並因此返回保留對象,但它將該對象添加到最近的autorelease pool,因此當該池將被排空時,該對象將被釋放。

1

在第二個示例中,您沒有創建該字符串。您只能通過調用以allocnewcopymutableCopy開頭的方法來創建對象。

如果您願意,您可以通過調用retain獲得所有權,但您也可以負責調用release。在這個例子中,沒有必要。你不再需要這個字符串。來電者用它做的是他們的責任。

當調用這樣的工廠方法時,通常會收到一個自動釋放對象。但你並不需要考慮這一點。因爲沒有創建它(因爲你沒有使用與allocnewcopy,或mutableCopy開頭的方法來獲取字符串),所有你需要做的是想保留計數三角洲 - 你需要保留它,以防止它從你下面消失。由於它只是返回給調用者,所以在這個例子中的答案是否定的。