2012-05-23 68 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以保持可变性的说明。 –