【问题标题】:Why are instance variables considered bad practice by Apple?为什么Apple认为实例变量是不好的做法?
【发布时间】:2014-01-12 12:40:32
【问题描述】:

在 Apple 的 Programming with Objective-C 中,Encapsulating Data 部分指出:

您可以在没有属性的情况下定义实例变量

当您需要跟踪一个值或另一个对象时,最好在对象上使用属性。

换句话说,他们强烈建议您对任何私有对象状态使用私有属性而不是实例变量。

我想知道为什么会这样?我知道属性具有 KVO 等特性和属性(强、弱......),但在许多情况下我不需要这些特性,实例变量就可以正常工作。

实例变量可能不被视为最佳实践有什么好的理由吗?

【问题讨论】:

  • 对于我的拙见,这是 Apple 的魅力——他们不会说“你可以”,而是说“你应该”:)
  • 总结 cmets 中的讨论并仔细阅读原文:Apple 没有说 私有变量是不好的做法,他们说 一般来说属性是最好的练习。而且,它是针对刚刚学习实例变量的人的一般性建议。
  • 这里有很多很好的一般性讨论:stackoverflow.com/questions/10432441/… 以及我相信已经回答了有关 Apple 文本的具体问题 :)
  • @ilyan。 - 感谢您的参考,虽然答案很弱“我相信现在(对于 ARC)的建议是使用属性来声明您的外部接口,但使用直接实例变量,其中变量是对象内部状态的一部分。” - 我很想看到这个建议的引用!
  • 要添加其他内容,使用属性时性能会受到轻微影响(因为您随后发送消息,而不是引用特定指针)。这通常是完全无关紧要的,但我曾经有过明显的差异(即紧密嵌套的循环,例如用于图像处理)。我很感激有一些方法可以解决这个问题,但这是值得考虑的事情。

标签: ios objective-c cocoa instance-variables


【解决方案1】:

尽管现在您的私有变量可能作为普通变量工作,但您稍后可能会决定某些属性“好东西”是有用的:

  • 观察
  • 原子访问器
  • 自定义访问器
  • 登录访问
  • 从子类访问

如果您仅将变量作为属性进行访问,则不会增加太多开销(除非在紧凑的周期中),并为获得上述任何好处留出空间。

基本上,即使您不打算公开属性,属性也很有用。

当然,在某些地方使用实例变量仍然“更自然”,例如,如果您在类集群中重新实现 Foundation 类(例如 NSArray),那么您的实现应该是私有的和高性能的,所以我不使用属性。

另外,我认为您不应该过多地阅读建议。对我来说,它更像是“如果您在 5 分钟前才了解属性和实例变量,那么让我们先从使用属性开始吧”

刚接触该语言的人可能会走得很远,但不知道实例变量是什么。

【讨论】:

  • 我明白你的意思,但我根本不同意使用某种技术的概念,因为你以后可能需要它的功能。这种方法可能导致软件过于复杂。如果我需要这些功能,我会使用属性。如果我不这样做,我会使用实例变量。我很乐意根据特定情况的要求在两者之间进行转换。无论如何 - 感谢您的回答,您的意见仍然非常感谢:-)
  • 好吧,我描述了一个使用属性的论据;有反对他们的平衡论点。
  • @ColinE,您的方法的问题是很难审核代码以确保正确使用。您必须查看每一个 ivar 访问并询问“我应该在这里使用访问器吗?”这会导致错误和难以维护的代码。一致性允许轻松审计,直接使用 ivar 使一致性变得不可能。由于在很多情况下必须使用属性,因此最好始终使用属性。这是 Apple 的观点,也是 ObjC 的最佳实践。
【解决方案2】:

换句话说,他们强烈建议您对任何私有对象状态使用私有属性而不是实例变量。

您从哪里得知他们推荐私有属性?我认为它们的意思是公共变量/属性。

当然,使用属性而不是公共实例变量有很多优点:

  • 封装和自定义 getter/setter
  • 内存管理
  • KVO
  • 二进制兼容性
  • 等等

但在我看来,使用 private 属性通常没有任何优势,而且使用私有实例变量要容易得多。我能想象的唯一原因是将来为此类变量制作自定义 getter/setter,但我认为这不是“最佳实践”。

【讨论】:

  • 这是最佳实践 A... 如果您确实需要,那么 example B 确实暗示 Apple 推荐模式 A 而不是 BB 此处是私有变量)。请注意,有时您需要它们(不仅是自定义设置器,还有观察和原子性,请参阅我的回答)。总的来说,他们有优势吗?正如我所说,作为初学者的建议,这是一个很好的建议。
  • “你从哪里读到他们推荐private属性?” - 好点,这里有一些歧义。我认为任何理智的开发人员都不会推荐公共实例变量!然而,短语“在需要跟踪值或另一个对象时,最好在对象上使用属性。”似乎确实暗示任何对象状态或对象之间的关联都应定义为属性。它当然没有说明这只是针对公共状态的建议。
  • 对于它的价值,我觉得私有财产也没有什么价值。例如,您何时需要将 KVO 用于“私有”对象?还是使用弱引用?
  • 我个人一直使用私有属性来提供对子类的访问,并在 setter 中实现自定义检查。我也使用实例变量,但从不导出它们,即使是子类。确实在这里没有看到 KVO 有多大用处:)
【解决方案3】:

重点在于存储抽象。如此简单却非常强大。

【讨论】:

    猜你喜欢
    • 2012-05-18
    • 1970-01-01
    • 2010-10-22
    • 2011-11-20
    • 2011-06-19
    • 2015-12-12
    • 2010-11-04
    相关资源
    最近更新 更多