需要有关Objective-c属性概念的帮助

S.J*_*S.J 5 objective-c ios

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

来自Apple Doc:

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

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

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

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

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

为什么要使用ivar来展示属性?它的好处是什么?当苹果说"使用存取方法或点语法是最佳实践"时

nie*_*bot 6

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

我遵循Apple的建议,尽量避免直接使用ivars.但有时你想要访问一个属性而不调用它的getter.我的代码中最常见的例外是lazily-initialized只读属性:

@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
Run Code Online (Sandbox Code Playgroud)

此外,您可能不希望为-dealloc方法中的属性调用getter ...例如,timer属性.要避免在其中创建计时器-dealloc,请直接访问ivar:

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

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

编辑:

此外,通过消息调度(使用dot-accessor语法或getter)与直接访问ivar来访问属性会有一些额外的开销,但几乎在所有情况下都没有区别.