可可开发人员教程指出,当声明时,所有实例变量都是私有的
存取器
默认情况下,Objective-C中的所有实例变量都是私有的,因此在大多数情况下,应该使用访问器来获取和设置值。有两种语法。这是传统的1.x语法:
[photo setCaption:@"Day at the Beach"]; output = [photo caption];
第二行的代码没有读取实例变量直接地它实际上是在调用一个名为caption的方法。在大多数情况下,你不加上";得到";Objective-C中getter的前缀。
不需要每次都需要访问器,这不是更容易吗?为什么它们自动被宣布为私有?
不需要每次都需要访问器,这不是更容易吗?
也许这会"更容易",但在大多数情况下,这只是不正确的。
setter是一个更好的例子,但也需要使用返回对象的getter。这种getter的典型(自动生成)实现与类似
- (Foo *)foo {
return [[_foo retain] autorelease];
}
这不是巧合——如果你只是直接摆弄对象的实例变量,那么一旦包含对象被释放,它的实例变量也会被释放,所以在释放后使用对象的属性是错误的。
有了setter,问题清单就更长了。同样,还有所有权问题:一个典型的setter会做一些类似的事情
- (void)setFoo:(Foo *)newFoo {
[newFoo retain];
[_foo release];
_foo = newFoo;
}
同样,如果你直接使用ivar,你要么只是简单地泄漏内存,要么需要手动、明确地跟踪所有权,这违反了DRY(而且非常容易出错)。
然后,关键值观察也不起作用。如果您只是更改对象内部的指针,注册的观察者将不会被告知这一点。当属性发生更改时,setter(以及其他人)负责发送适当的键值观察者消息。
不,这并不容易,事实上语法是相似的。
self->_caption;
_caption; // here self-> is implicit.
与。
[self caption];
self.caption;
我认为直接访问ivar比访问更容易的说法并不准确。
访问器的原因是抽象。它可以对访问器的功能进行子类化和替换。可以重构内部,但将相同的接口留给访问器。访问器比直接访问ivar更灵活、更实用。