2

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

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

@interface Foo : NSObject

@property (strong) NSString *someString;

@end

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

someLabel.text = self.someString;

someLabel.text = _someString;

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

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

谢谢

4

3 回答 3

4

如您所知,调用self.someString确实是[self someString]. 如果您选择创建一个属性,那么您应该使用该属性。该属性可能添加了其他语义。也许该属性是延迟加载的。也许该属性不使用 ivar。调用属性的 getter 可能还有一些其他需要的副作用。也许现在没有,但也许这在未来会发生变化。现在调用该属性会使您的代码更具前瞻性。

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

但最终,它是您的代码、您的财产、您的 ivar。您知道为什么要添加属性。您知道该财产的任何潜在好处(如果有的话)。

于 2012-10-24T22:40:15.143 回答
2

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

实际上有很多充分的理由考虑使用访问器而不是直接公开类的字段——不仅仅是封装的论点和使未来的变化更容易。

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

  • 封装与获取或设置属性相关的行为——这允许以后更容易地添加附加功能(如验证)。
  • 隐藏属性的内部表示,同时使用替代表示公开属性。
  • 使您的公共接口免受更改 - 允许公共接口在实现更改时保持不变,而不会影响现有消费者。
  • 控制属性的生命周期和内存管理(处置)语义 - 在非托管内存环境(如 C++ 或 Objective-C)中尤为重要。
  • 为属性在运行时更改时提供调试拦截点 - 在某些语言中,如果没有此属性,调试属性更改为特定值的时间和地点可能会非常困难。
  • 改进了与旨在针对属性 getter/setter 操作的库的互操作性 - 想到了模拟、序列化和 WPF。
  • 允许继承者更改属性行为方式的语义,并通过覆盖 getter/setter 方法来公开。
  • 允许 getter/setter 作为 lambda 表达式而不是值传递。
  • getter 和 setter 可以允许不同的访问级别——例如 get 可能是公共的,但 set 可以是受保护的。
于 2012-10-24T22:48:57.743 回答
1

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

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

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

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

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

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

对于可变对象不要创建属性。

于 2012-10-25T05:56:22.837 回答