Objective C - 使用属性获取访问器与直接使用 iVar
Posted
技术标签:
【中文标题】Objective C - 使用属性获取访问器与直接使用 iVar【英文标题】:Objective C - Using property get accessor vs directly using iVar 【发布时间】:2012-10-24 22:31:04 【问题描述】:我想知道使用 (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 呢?
如果没有区别,是否有一种方法被认为是最佳实践?
谢谢
【问题讨论】:
【参考方案1】:如您所知,调用self.someString
确实是[self someString]
。如果您选择创建一个属性,那么您应该使用该属性。该属性可能添加了其他语义。也许该属性是延迟加载的。也许该属性不使用 ivar。调用属性的 getter 可能还有一些其他需要的副作用。也许现在没有,但也许这在未来会发生变化。现在调用该属性可以使您的代码更具前瞻性。
如果您有一个 ivar 和一个属性,请使用该属性,除非您有明确的理由改为使用 ivar。可能存在您不希望执行该属性的任何额外语义或副作用的情况。所以在这种情况下,直接使用 ivar 比较好。
但归根结底,它是您的代码、您的财产、您的 ivar。您知道为什么要添加属性。您知道该财产的任何潜在好处(如果有的话)。
【讨论】:
【参考方案2】:我想这就是你要找的。 Why use getters and setters?
实际上有很多充分的理由考虑使用访问器而不是直接公开类的字段 - 不仅仅是封装的参数和使未来的更改更容易。
以下是我知道的一些原因:
封装与获取或设置相关的行为 属性 - 这允许附加功能(如验证) 以后更容易添加。 隐藏内部表示 属性,同时使用替代方法公开属性 表示。 使您的公共界面免受更改 - 允许公共接口保持不变,而 在不影响现有消费者的情况下更改实施。 控制生命周期和内存管理(处置)语义 的属性——在非托管内存中特别重要 环境(如 C++ 或 Objective-C)。 提供调试 属性在运行时更改时的拦截点 - 调试 属性更改为特定值的时间和地点可能相当 在某些语言中没有这个就很困难。 改进的互操作性 带有旨在针对财产进行操作的库 getter/setter - 模拟、序列化和 WPF 浮现在脑海。 允许继承者更改属性的语义 行为并通过覆盖 getter/setter 方法公开。 允许 getter/setter 作为 lambda 表达式传递 而不是价值观。 getter 和 setter 可以允许不同的访问 级别 - 例如,获取可能是公开的,但集合可能是 受保护。【讨论】:
感谢您的详细解释,但我的问题不是为什么要使用访问器,而是如果我已经拥有一个属性(私有或公共无关紧要),使用之间有什么区别getter (self.someProperty) 并使用 iVar (_someProperty)。但是还是谢谢 :) 哦,好吧。明白了。没有大的区别。唯一方便的是,在以后的某个时间点,您可以重新实现您的 getter,并在有人尝试访问它时添加一些新功能。说在稍后阶段你想在控制台中打印值,每当有人访问你的参数但参数在你的代码中的任何地方都使用。在这种情况下,您只需要在类中实现您的 getter 方法。自动执行的任何操作都将在所有其他地方正常工作。【参考方案3】:我不是一个很有经验的人来回答这个问题,尽管我试图通过查看大约 10 年前的源代码来表达我的观点和经验。
在早期的代码中,他们创建了 ivars 和属性/综合。现在只使用属性/综合。我看到的一个好处是代码更少并且没有混淆。
混乱!!!是的,如果 ivars 及其属性具有不同的名称,那么如果您在一段时间后阅读自己的代码,它确实会给其他人甚至您造成混淆。因此,请为 ivar 和属性使用一个名称。
通过使用属性,KVO/KVB/KVC 会自动处理,这是肯定的。
@property/@synthesise 将您的 ivar 设置为 0/nil 等。
如果您的子类包含相同的 ivar,也很有帮助。
对于可变对象不要创建属性。
【讨论】:
以上是关于Objective C - 使用属性获取访问器与直接使用 iVar的主要内容,如果未能解决你的问题,请参考以下文章
Objective-C:在不可见的自定义 UITableViewCell 上获取属性的值