【问题标题】:With ARC why use @properties anymore?有了 ARC,为什么还要使用 @properties?
【发布时间】:2012-03-26 17:02:20
【问题描述】:

在非 ARC 代码中,保留属性使用 self.property = 语法轻松地为您处理内存管理,因此我们被教导将它们用于几乎所有事情。

但是现在有了 ARC,这种内存管理不再是问题,那么使用属性的理由是否消失了?还有什么好的理由(显然除了提供对实例变量的公共访问之外)再使用属性吗?

【问题讨论】:

    标签: objective-c ios xcode automatic-ref-counting


    【解决方案1】:

    但现在有了 ARC,这种内存管理不再是问题,所以 使用属性蒸发的原因?还有什么好的吗 原因(显然不是提供对实例的公共访问 变量)来使用属性了吗?

    是的——通过使用@property 和@synthesized getter/setter,您保证:

    • 您的 getter/setter 可以被子类化,子类可以覆盖存储和/或行为
    • 一切都很好地封装
    • 您可以使用观察挂钩(KVO 等...)来监控内部和外部的变化
    • 您可以方便地在读取和/或写入属性时设置断点
    • 如果需要公开“仅内部”实例变量,只需复制@property 声明本身即可;更少的重构。
    • 您可以利用所有各种修饰符关键字(复制、强、弱、原子等)的声明能力。编译器正越来越多地利用这些关键字

    即使在类内部,我通常也倾向于使用属性和点语法来维护对象内的状态。这并不是普遍正确的——如果我的设计是这样的,那么我会直接操纵一些实例变量(完全直接操纵;根本没有@property),如果我的设计暴露意味着无论如何都要进行大规模的重构。

    【讨论】:

    • 此外,属性还可以更轻松、更安全地添加复制语义和原子语义。加上使用@synthesize propname = ivarname; 创建一个具有一个名称的属性和一个具有另一个名称的实例变量;总是有用的。
    • 同意,感谢您的回答。我还想补充一点,关于@property 性能与 ivars 的讨论很多。我敢于让您找到非原子属性和 ivar 之间的性能差异......这可能是不可估量的可以忽略不计。
    • 您是否也同意修饰符关键字weak、strong、atomic等在您的api中对您以及arc本身都是有用的标志来理解您的意图?
    【解决方案2】:

    那么使用属性的原因就消失了吗?

    随着 ARC 为 ivars 提供“所有权魔法”,人们选择属性而不是 ivars 的这一特定方面确实消失了。但是,还有许多其他人:

    • 原子/非原子区分可用于属性,不适用于 ivars
    • 属性提供的灵活性(只读/读+写区别)不适用于 ivars
    • ivars 无法执行计算和参数检查

    我继续使用属性作为保持可能暴露给外部类或内部“兄弟”类的状态的默认方式,因为额外的灵活性超过了运行时的小额额外成本。

    【讨论】:

      【解决方案3】:

      我不认为我曾经仅仅因为内存管理而使用过属性,我认为你也不应该这样做。所以要回答你的问题,不,除了访问实例变量之外,没有理由使用属性,这本质上是它们应该首先用于的目的。

      【讨论】:

      • 如果您没有使用过属性,那么您可能做错了。 “有时它可能看起来乏味或迂腐,但如果你始终使用访问器方法,内存管理出现问题的可能性就会大大降低。如果您在整个代码中对实例变量使用保留和释放,那么您几乎可以肯定做错了事。” — 内存管理编程指南,Apple
      • @DaveBatton 引用不适用于 ARC
      • @JesseGumpo 同意,它不适用于 ARC。我打算让它适用于凯文的评论,即他从来没有“仅仅因为内存管理而使用属性......”
      【解决方案4】:

      你在谈论两个不同的事情。 ARC 用于管理内存,因此您不必背负大量的 dealloc 和 retain 语句。

      属性可以让类有机会控制/限制其内部 iVar 的公开,公开 API 以供其他类进行通信/交互。

      【讨论】:

        【解决方案5】:

        除了保留之外,还有其他修饰符有时会变得非常有用,例如'copy' 将块分配给类成员变量时,或 'readonly' 确保无法写入属性。另外不要忘记使用 Core Data 时的“dynamic”属性,以及在分配或检索属性时执行自定义代码的可能性(在定义自定义 getter/setter 而不是使用@synthesize 时)。

        【讨论】:

          猜你喜欢
          • 2020-11-03
          • 2015-02-15
          • 2012-02-04
          • 2020-04-14
          • 2023-04-02
          • 2017-11-13
          • 2021-06-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多