Objective-C中的私有变量



可可开发人员教程指出,当声明时,所有实例变量都是私有的

存取器

默认情况下,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更灵活、更实用。

相关内容

  • 没有找到相关文章

最新更新