5

我正在阅读Apple Doc以了解属性实例变量,但有点困惑

来自苹果文档:

大多数属性都由实例变量支持 默认情况下,读写属性将由实例变量支持,该实例变量将再次由编译器自动合成。

实例变量是一个存在并在对象生命周期内保持其值的变量。用于实例变量的内存在第一次创建对象时分配(通过 alloc),并在对象被释放时释放。

除非您另外指定,否则合成的实例变量与属性具有相同的名称,但带有下划线前缀。例如,对于名为 firstName 的属性,合成的实例变量将称为 _firstName。

尽管对象使用访问器方法或点语法访问自己的属性是最佳实践,但可以直接从类实现中的任何实例方法访问实例变量。下划线前缀清楚地表明您正在访问实例变量,而不是例如局部变量:

如果使用访问器方法或点语法是最佳实践,那么为什么要使用用户 _ivarPropertyName?

为什么使用 ivar 来呈现属性?它有什么好处?当苹果说“使用访问器方法或点语法是最佳实践”时

4

1 回答 1

6

@property声明一个属性的存在(描述它的接口),但没有指定该属性的实现。但是属性需要将其内容存储在某个地方。默认情况下,编译器会为此合成一个ivar(以及匹配的 setter 和 getter)。所以通常你可以忽略ivar的存在而只使用点语法

我遵循 Apple 的建议并尽量避免直接使用ivars。但有时你想在不调用它的 getter 的情况下访问一个属性。我的代码中最常见的例外是延迟初始化的只读属性:

@interface MyObject : NSObject
@property ( nonatomic, readonly ) id someProperty ;
@end

@implementation MyObject
@synthesize someProperty = _someProperty ; // required; compiler will not auto-synthesize ivars for readonly properties

-(id)someProperty
{
    if ( !_someProperty )
    {
        _someProperty = ... create property here
    }

    return _someProperty ;
}

@end

此外,您可能不想在您的-dealloc方法中为某个属性调用 getter……例如,计时器属性。为避免在 中创建计时器-dealloc,请直接访问 ivar:

-(void)dealloc
{
    [ _myTimer invalidate ] ; // don't use self.myTimer here, that would create a timer even though we're going away...
}

可能还有更多用例。对于大多数属性,您甚至不需要使用 ivar,只需使用<value> = self.propertyand self.property = <new value>

编辑:

此外,通过消息调度(使用点访问器语法或 getter)访问属性与直接访问ivar 相比,会产生一些额外的开销,但在几乎所有情况下都没有区别。

于 2013-03-19T07:47:21.900 回答