目标C - 使用属性get accessor vs直接使用iVar

时间:2012-10-24 22:31:05

标签: objective-c ios cocoa-touch cocoa properties

我想知道使用(get)访问器读取属性值和直接使用iVar之间究竟有什么区别?

假设我有一个声明属性的类:

@interface Foo : NSObject

@property (strong) NSString *someString;

@end

在实施中我正在使用它。以下两行之间是否存在任何差异:

someLabel.text = self.someString;

someLabel.text = _someString;

对于set accessors,很明显。 Afaik强大的属性访问者负责保留和释放(一个有趣的'副问题'将是ARC如果改变它,即直接设置iVar [假设它不是__weak iVar]也使用ARC正确保留和释放),也KVO需要使用访问器才能正常工作等。但是getter呢?

如果没有区别,是否有一种方法被认为是最佳实践?

THX

3 个答案:

答案 0 :(得分:4)

如您所知,致电self.someString的确是[self someString]。如果您选择创建属性,则应使用该属性。可能还有其他语义添加到属性中。也许这个属性是懒惰的。也许该物业不使用伊娃。也许还有一些其他需要的副作用来调用属性的getter。也许现在还没有,但未来可能会发生这种变化。现在调用该属性可以使您的代码更具未来性。

如果您有ivar和属性,请使用该属性,除非您有明确的理由使用ivar。可能存在您不希望执行属性的任何额外语义或副作用的情况。所以在这种情况下,直接使用ivar会更好。

但最终,这是你的代码,你的财产,你的伊娃。你知道为什么你添加了一个属性。您知道该财产的任何潜在好处,如果有的话。

答案 1 :(得分:2)

我认为这就是你要找的东西。 Why use getters and setters?

考虑使用访问器而不是直接暴露类的字段,实际上有许多充分的理由 - 除了封装的参数和使未来的更改更容易。

以下是我所知道的一些原因:

  • 与获取或设置相关联的行为的封装 property - 这允许其他功能(如验证) 以后更容易添加。
  • 隐藏内部代表 使用替代方案暴露财产时的财产 表示。
  • 将您的公共界面与变更隔离开来 - 允许公共接口保持不变 实施变更而不影响现有消费者。
  • 控制生命周期和内存管理(处置)语义 属性 - 在非托管内存中尤为重要 环境(如C ++或Objective-C)。
  • 提供调试 属性在运行时更改时的拦截点 - 调试 属性何时何地变为特定值可能相当 在某些语言中没有这个很难。
  • 改进了互操作性 使用旨在对抗财产的图书馆 getter / setters - Mocking,Serialization和WPF浮现在脑海中。
  • 允许继承者更改属性的语义 通过覆盖getter / setter方法来表现和暴露。
  • 允许getter / setter作为lambda表达式传递 而不是价值观。
  • Getters和setter可以允许不同的访问 等级 - 例如,获取可能是公开的,但设置可能是公共的 保护。

答案 2 :(得分:1)

我不是一个非常有经验的人来回答这个问题,即使我试图通过查看大约10岁的源代码来提供我的观点和经验。

在早期的代码中,他们创建了ivars和属性/综合。如今只使用属性/合成。我看到的一个好处是代码少,没有混淆。

混乱!是的,如果ivars及其属性具有不同的名称,如果您在一段时间后阅读自己的代码,它确实会给其他人甚至是您造成混淆。因此,为ivar和property使用一个名称。

通过使用属性KVO / KVB / KVC会自动处理,这是肯定的。

@ property / @ synthesise将你的ivar设置为0 / nil等。

如果您的子类包含相同的ivar,也会有所帮助。

对于可变对象,不要制作属性。