您应该始终使用属性的访问器(在 Objective-C 2.0 中意味着使用self.property
符号。)
为什么?因为它提供了自动访问控制和对象生命周期管理。生成的访问器可以提供很多保护,例如读/写、复制、保留等,否则需要大量手动代码。如果您编写自己的访问器,则可以添加所需的所有验证和副作用。
(早在 Objective-C 2.0 编写访问器之前就被认为是一门高雅艺术。如果你充分利用潜力,它仍然可以是一门高雅艺术。)
唯一应该直接访问属性的时候是编写访问器时。例如,采用以下常见模式:
@property(nonatomic, retain) NSMutableArray *myObjects;
@synthesize myObjects;
-(NSMutableArray *) myObjects{
if (myObect!=nil) {
return myObect;
}
NSMutableArray *anArray=[[NSMutableArray alloc] initWithCapacity:1];
self.myObject=anArray;
[anArray release]
return myObject;
}
- 这个访问器确保 myObjects 永远不会为零,这消除了代码其余部分中的大量样板 nil 测试。
- 你显然不能打电话
self.myObjects
(这实际上是 [self myObjects] )在访问器内部,而不创建无限递归,因此您必须在此处访问原始变量,但是......
- ...您可以调用(自动生成的)
self.myObjects=
(这实际上是 [self setMyObjects:anArray] )因为它是一个完全不同的方法。如果您查看 setMyObjects: 的内部结构,您会发现它也访问原始变量。
- 如果您使用生成的访问器,
self.myObjects=
每次您调用它时,都会为您处理保留、复制、清空等。唯一需要调用release 的时间是在dealloc 中。仅此一项就可以消除人们在 Objective-C 中所犯的错误的一半。
相反,在访问器方法之外,直接访问类自己的方法内的属性绝对不会获得任何好处。它所做的只是节省一些按键操作,同时让您面临难以发现错误的风险。
正如前面的答案所示,您在尝试直接管理属性时犯了几个内存错误。如果您每次都使用访问器,您就不会制作它们。例如:
pickerData = [[[NSArray alloc] initWithObjects:@"A", @"B", @"C", nil] retain];
...每次都必须正确管理,而...
self.pickerData = [[NSArray alloc] initWithObjects:@"A", @"B", @"C", nil];
...自动正确。
请记住,任何 Objective-C 类的最终设计目标都是应该完全模块化和可重用。这意味着它应该管理自己的所有内存、自己的数据验证和自己的副作用。访问器对于该管理绝对至关重要。通过将逻辑包装在变量的每次访问周围,您可以确保 (1) 它是您期望的类型、范围等,并且 (2) 当您需要它时它始终存在 (3) 您可以控制所有方面写入或读取变量的影响以及 (4) 它不会泄漏。
我对访问器的优点赞不绝口。事实上,我可能会写一首小歌。 ;-)