2012-05-23 23 views
4

我下面的官方教程你的第二個iOS應用:故事板它告訴我申報了財產masterBirdSightingList像這樣(只是一個具體的例子,並沒有必要知道上下文):分配NSMutableArray裏與@property和「複製」屬性

@property (nonatomic, copy) NSMutableArray *masterBirdSightingList; 

注意,有一個屬性複製。然後合成這種特性:

@synthesize masterBirdSightingList = _masterBirdSightingList; 

而旁邊還有這讓我困惑一個init方法:

- (void)initializeDefaultDataList { 
NSMutableArray *sightingList = [[NSMutableArray alloc] init]; 
self.masterBirdSightingList = sightingList; 
[self addBirdSightingWithName:@"Pigeon" location:@"Everywhere"]; 
} 

絕對sightingList分配的空間,那麼它分配給masterBirdSightingList財產。不過,該屬性有副本屬性。這意味着實例變量_masterBirdSightingList將被分配給另一空間以保留來自sightingList的東西。爲什麼?爲什麼不直接像這樣的財產分配空間:

self.masterBirdSightingList = [[NSMutableArray alloc] init]; 
+4

他們是一樣的。 – kennytm

+0

我不知道該聲明self.masterBirdSightingList = sightingList只是一個簡單的複製操作,只複製引用OR它會分配一個新的空間來存儲內容? thx – lookof

+2

值得關注的東西:通常,一個「可變」對象的-copy方法將返回非可變變體(在你的情況下,一個NSArray)。爲了防止發生異常,您必須自己編寫setter方法來調用-mutableCopy。 –

回答

7

在Objective-C,在財產copy屬性單元合成看起來像這樣的setter:

-(void)setMasterBirdSightingList:(NSMutableArray*)newValue 
{ 
    if (_masterBirdSightingList == newValue) return; 
// NSMutableArray* oldValue = _masterBirdSightingList; 
    _masterBirdSightingList = [newValue copy]; 
// [oldValue release]; // <-- not applicable in ARC. 
} 

和點語法會總是被翻譯成

[self setMasterBirdSightingList:sightingList]; 

不管屬性的屬性。

通過-copy方法完成「分配給另一個空間來保存來自sightingList的東西」的東西。將參數傳遞給setter的newValue參數的方式是無關緊要的。


編輯:如在評論中提及@David,一個可變類型的-copy方法返回一個不可變的對象。您必須改寫setter才能調用-mutableCopy。見What's the best way to use Obj-C 2.0 Properties with mutable objects, such as NSMutableArray?

+0

我希望能夠用'isEqual:'進行比較。 –

+0

@HotLicks:不,他們不應該與'-isEqual:'進行比較。當'-copy'返回相同的值(可能使用不可變類型)並且使用'self.foo = self.foo'時,'=='主要用於避免雙重釋放。 – kennytm

+1

我看了一下教程,它包含了關於重寫setter以保持可變性的說明。 –