2011-06-09 70 views
0

這可能是一個愚蠢的問題,但在TableView的介紹中,作者具有NSArray * listData的屬性來填充虛擬數據表。在viewDidLoad中,他基本上做到這一點:開始iPhone手冊中的TablewView示例

- (void)viewDidLoad { 
NSArray *array = [[NSArray alloc] [email protected]"1", @"2", @"3", more stuff, nil]; 
self.listData = array; 
[array release]; 
... 
} 

爲什麼他創建另一個陣列,並將其設置爲屬性,而不是做一些像

- (void)viewDidLoad { 
listData = [[[NSArray alloc] [email protected]"1", @"2", @"3", more stuff, nil]autorelease]; 

的是它使用的alloc管理內存更好/ init與autorelease池?或者是第二種方法不起作用?謝謝。

回答

1

您的代碼有誤,可能會崩潰。在他的代碼中,他稱alloc,意思是保留計數爲1.然後,他將其分配給一個屬性。我假設這個屬性被聲明爲retain,在這種情況下,保留計數將上升到2.然後,他叫release,其下降的保留計數回到1

在你的代碼,你叫alloc,這意味着保留計數爲1,那麼您可以撥打autorelease,這意味着保留計數將降至0,並且對象的內存將很快解除分配。您將對象分配給實例變量 - 而不是像他那樣保留的屬性 - 因此您不會再增加保留計數。這意味着你將留下一個指向內存的懸掛指針,隨時可以用其他任何東西覆蓋它。當您嘗試訪問listData時,您會崩潰,因爲它可能已被覆蓋。如果你不明白這裏發生了什麼,請閱讀Memory Management Programming Guide

話雖如此,你問題的核心是有效的。除了分配給保留屬性而不是實例變量之外,沒有什麼能夠阻止他像你一樣做同樣的事情。

+0

我還是習慣了「自我」。在我的代碼片段中,我的意思是指用retain聲明的listData屬性。在這種情況下,我是否必須有自己的意見才能提及該財產?否則,它只是在該方法的範圍內的伊娃? (對不起,一些OOAD,道具,Ivars仍在沉沒中)。謝謝。 – Crystal 2011-06-09 15:46:33

+0

當你聲明和合成一個屬性時,一個實例變量會與一個getter和一個setter一起被創建爲具有相同名稱。如果該屬性被聲明爲「保留」,那麼當您將一個對象分配給該屬性時,合成的設置者將向該對象發送「保留」消息。如果你不使用'self.',那麼你沒有分配屬性,你繞過了setter並直接分配給實例變量,所以對象的保留計數不會增加。 – Jim 2011-06-09 15:50:52

+0

這不是真正的範圍。一個實例變量是一個變量,它是一個對象的一部分(一個對象僅僅是一個類的*實例*)。範圍只是相關的,因爲保留計數爲0的自動釋放對象只能保證不會在當前範圍內釋放(或多或少)。 – Jim 2011-06-09 15:52:50