2011-07-24 120 views
0

我始終認爲,我們所使用的中間對象,例如,創建一個數組來填補另一個數組:使用中介的初始化對象

characters = [[NSArray alloc] initWithObjects:@"Antony", @"Artemidorus", @"Brutus", nil]; 
play.characters = characters; 
[characters release]; 

characters的對象是一個NSArrayplay

我看到與@property及其self相同的東西:我們沒有直接將新項目添加到此屬性中,就像我們在上面的示例中沒有直接填寫characters一樣。這只是關於「風格」嗎?

回答

1

實際上在這小段代碼中只有一個陣列正在播放。

它不是中間數組,而是變量持有指向它的指針 - 在這種情況下是變量字符。

這是發生了什麼:

表達

[[NSArray alloc] initWithObjects:@"Antony", @"Artemidorus", @"Brutus", nil] 

分配一個對象,有三個NSString的(它們本身是對象,但讓我們留下了一會兒)初始化它。初始化還包括保留計數的增量,所以它是一個起點。

這個新創建的對象位於內存中的某個特定位置,比如0100H。這個位置然後被存儲在變量characters中。用C術語來說,characters是一個指向對象的指針。

然後,對象play的屬性@"characters"被設置爲指向與局部變量characters相同的內存位置。因此,現在有兩個變量(其中一個也是屬性)指向相同的對象,或者,如果您願意,可以指向內存中的相同位置。如果屬性是保留類型,則會自動遞增對象的保留計數,因此它現在是2.

隨着最後一行中的釋放消息,對象將其保留計數遞減1,因此在此代碼片段的末尾,該對象由play.characters屬性指向,並且其保留計數爲1。

要真正乾淨,這段代碼可能應該設置局部變量爲nil,以避免變量之間持有指向對象的指針和保留計數之間的混淆。

所有這些都是爲了表明這裏真的只有一個數組,而是指向它的兩個變量。所以沒有太多的計算機資源被乍一看看浪費了。

如果你想做到這一切在一個單一的線,你可以寫這樣的事情:

play.characters = [[[NSArray alloc] initWithObjects:@"Antony", @"Artemidorus", @"Brutus", nil] autorelease]; 

但這個確切的工作還不太清楚,因爲它涉及到那些神祕的自動釋放的一個,即一個自動處理並推遲到稍後階段的發佈。

這是一個很長的描述,但我希望它能說明發生了什麼。

+0

感謝Monolo,很好的回答,現在它更有意義。乾杯 – Paul

+0

嗨Monolo,我只是問:在相同的代碼中,我發現:NSString * cellText = nil; cellText = play.genre;在DetailVC中,我們可以編寫一個指針,把一些數據放在裏面,甚至不用alloc-init NSString,因爲我們有對象Play的「保留」,是嗎?再次感謝 – Paul

+0

如果變量cellText在方法中的一組大括號(範圍)內定義,**和**您分配發生在同一範圍內,**和**'play.genre'未被賦值其他東西(這意味着它保存的對象會失去保留計數),是的。 – Monolo

2

這不是一個風格的問題。

play.characters是一個屬性,並可以「​​包含」一個現有的陣列或nil,但即使「包含」現有的陣列,你不能改變一個NSArray的內容,所以你必須創建一個新的,並分配給該屬性。

如果聲明瞭所有聲明,那麼分配給屬性將導致其setter方法運行(如果您使用@synthesize或由您編寫代碼,則可由編譯器創建),並且將處理刪除任何現有陣列,分配新陣列並保留它。

+0

好的謝謝它是有道理的,謝謝你的回覆! – Paul