Objective-C中属性覆盖的危害是什么?

时间:2011-04-13 14:28:43

标签: objective-c properties override class-extensions

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

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

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

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

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

2 个答案:

答案 0 :(得分:5)

对于您提到的每种情况,都有一个适当的位置,在野外使用频率不同。你只需要小心不要踩到自己。我将举例说明我个人遇到过的事。

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

私有财产
这比你给它的功劳更有用。私有财产的替代方案是普通的'ivar',我们都熟悉它。如果这是一个以某种频率发生变化的ivar,你最终会得到如下代码块:

[_myIvar release], _myIvar = nil;

或:

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

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

self.myIvar = someValue;

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

公开读取,私下读写
这只是标准做法。你是对的,它是有用的,而且它也没有危险,因为属性在标题中。任何人意外地压倒它都只能归咎于自己。

答案 1 :(得分:0)

好问题

  1. 使用这个就是你 开发者应该知道你是什么 在这一点上做,需要添加 对基类的自定义 属性。既然你知道什么 你在做什么你会正确地打电话 除非super的实现 你有充分的理由不去。该 决定不叫超级可能 特别是在情况下有害 你不知道基地在哪里 课程已实施。

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

  3. 是的,你是对的,这是有益的 限制进入您的财产。

  4. #2的例子

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