【问题标题】:What's the harm of property override in Objective-C?Objective-C 中属性覆盖的危害是什么?
【发布时间】:2011-08-04 18:52:12
【问题描述】:

在几种情况下,您可能会覆盖超类的属性。

  1. 您声明了一个与它的名称和属性相同的属性 超类'。(因为如果你改变 属性你可以得到一个编译器 警告)。你可以合成 使用您创建的 ivar。什么是 这个的用途?或者有什么害处 可以吗?

  2. 如果超类在类扩展(类别 没有名字),那么它可能不是 在头文件中。如果你不 从标题中知道该属性 文件,可以声明同名 具有任何属性的财产或 你想要的课。但是 setter/getter 方法将覆盖 那些“秘密财产”。 我认为这只会造成伤害。但 因为你不知道从标题 文件,如何避免这种情况?

  3. 您可以将头文件中的属性声明为“只读”并在 类扩展将其重新声明为 “读写”。我认为这是 它可以做得很好。

我对这些情况的理解正确吗?而且我不知道第一种和第二种情况有什么好处。但是如果我想避免第一种情况,我可以在声明之前检查子类是否已经具有该属性。但是如果该属性不在公共头文件中,如第二种情况,我只是不知道该怎么办。

【问题讨论】:

    标签: objective-c properties overriding class-extensions


    【解决方案1】:

    您提到的每种情况都有一个合适的地方,在野外使用的频率各不相同。你只需要小心不要踩到自己。我会用我个人遇到的例子来说明。

    子类化以故意覆盖属性
    在这种情况下,就像 Joe 提到的那样,在覆盖属性之前,您最好确切地知道自己在做什么并且没有其他选择。我个人发现,为已经存在的属性覆盖单个 setter 或 getter 来实现自定义通常就足够了,而不是重新声明和合成属性。例如,考虑一个专门的 UIView 子类,它只有具有 UIClearColor 背景才有意义。要强制执行此操作,您可以覆盖 -setBackgroundColor: 以仅打印警告消息,然后不调用 super 的实现。我会说我从来没有理由完全覆盖一个属性,但我不会说它在某些需要完全劫持现有属性的情况下不是一个有用的工具。

    私有财产
    这比你认为的更有用。私有财产的替代品是普通的 ol' ivar,我们都熟悉。如果这是一个以某种频率变化的 ivar,您最终会得到如下所示的代码块:

    [_myIvar release], _myIvar = nil;
    

    或:

    [_myIvar release];
    _myIvar = [someValue retain];
    

    虽然看起来还不错,但像这样的内存管理样板代码会变得非常陈旧,非常快。或者,我们可以将上面的示例实现为具有保留语义的私有属性。这意味着,无论如何,我们只需要:

    self.myIvar = someValue;
    

    一段时间后,这对眼睛和手指来说会容易得多。您注意到这一点是正确的,因为这个属性对宇宙的其他部分是不可见的,它可能会意外地被子类覆盖。这是在 Objective-C 中开发时的固有风险,但您可以采取措施使风险变得非常小。这些措施是以可预测的方式修改您的私有财产名称的变体。您可以在这里采取无数条道路:例如,您将私人财产名称前加上您的姓名首字母和下划线作为个人政策。对我来说,我会得到类似mw_ivar 的东西,以及相应的-setMW_ivar:-mw_ivar 访问器。是的,从统计上讲,有人可能会出现并意外覆盖该名称,但实际上,他们不会。特别是如果您有办法将您的实践发布给可能使用您的代码的人。而且,我可以肯定地说,Apple 并没有四处走动并制造以这种方式破坏的私有财产,因此您在这方面也很安全。

    公开只读,私密读写
    这只是标准做法。你是对的,它很有用,而且它并不危险,因为属性在标题中。任何不小心覆盖它的人都只能怪自己。

    【讨论】:

    • 在这个很好的答案中您缺少的另一个用例是在子类上指定更具体的类型。 IE。您在父级上有一个 id 类型的属性。在子类上,您可以通过重新声明属性(例如NSString*)然后在子类中使用@dynamic propertyName 来通知编译器使用父类中的存储来使这一点更加具体。
    【解决方案2】:

    好问题

    1. 使用这个是你作为 开发者应该知道你是什么 在这一点上做,需要添加 基类的自定义 财产。既然你知道什么 你在做什么你会正确地打电话 supers 的实现,除非 你有充分的理由不这样做。这 决定不叫 super 可能是 有害的,尤其是在某些情况下 你不知道基地如何 类已实现。

    2. 是的,这是有害的,但可以 通过不过度使用类别来避免 并仔细选择一个名字 属性或方法并考虑 前缀。

    3. 是的,你是对的,这对 限制访问您的财产。

    #2 的示例

    @interface UIView(PFXextended)
    -(NSArray*)PFXGetSubviewsOfType:(Class)class;
    @end
    

    【讨论】:

      猜你喜欢
      • 2019-10-14
      • 1970-01-01
      • 2017-08-29
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 2011-07-17
      • 1970-01-01
      • 2015-09-12
      相关资源
      最近更新 更多