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

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

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

@interface Foo : NSObject @property (strong) NSString *someString; @end 

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

 someLabel.text = self.someString; someLabel.text = _someString; 

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

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

谢谢

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

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

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

我想这就是你要找的东西。 为什么要使用getter和setter?

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

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

  • 与获取或设置属性相关联的行为的封装 – 这允许稍后更容易地添加附加function(如validation)。
  • 隐藏属性的内部表示,同时使用替代表示公开属性。
  • 使公共接口与变更隔离 – 允许公共接口在实现更改时保持不变,而不会影响现有的使用者。
  • 控制属性的生命周期和内存管理(处理)语义 – 在非托管内存环境(如C ++或Objective-C)中尤为重要。
  • 为属性在运行时更改时提供调试拦截点 – 在某些语言中调试属性更改为特定值的时间和位置可能非常困难。
  • 改进了与旨在针对属性获取器/设置器进行操作的库的互操作性 – 可以想到模拟,序列化和WPF。
  • 允许inheritance者通过重写getter / setter方法来更改属性的行为和暴露的语义。
  • 允许getter / setter作为lambda表达式而不是值传递。
  • getter和setter可以允许不同的访问级别 – 例如get可以是公共的,但是set可以受到保护。

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

在早期的代码中,他们创造了伊莎和财产/综合。 现在只使用属性/合成。我看到的一个好处是代码少,没有混淆。

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

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

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

如果你的子类包含相同的ivar也很有帮助。

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