Jim*_*mmy 18 overriding properties objective-c class-extensions
在某些情况下,您可能会覆盖超类的属性.
您声明一个属性与其超类的名称和属性相同.(因为如果您更改属性,则可以获得编译器警告).您可以使用您创建的ivar进行合成.这有什么用?或者它有什么危害呢?
如果超类在类扩展(没有名称的类别)中声明属性,则它可能不在头文件中.如果您不知道头文件中的该属性,则可以使用您想要的属性或类声明相同的名称属性.但是setter/getter方法将覆盖那个"秘密属性"的方法.我认为这只会造成伤害.但既然你不知道头文件,你怎么能避免这个?
您可以将头文件中的属性声明为"readonly",并在类扩展中将其重新声明为"readwrite".我认为这是可以做得好的情况.
我对这些情况的了解是否正确?我不知道第一和第二种情况可以做些什么.但是如果我想避免第一种情况,我可以在声明之前检查子类是否已经具有该属性.但是如果属性不在公共头文件中,就像在第二种情况下那样,我只是不知道该怎么做.
对于您提到的每种情况,都有一个适当的位置,在野外使用频率不同.你只需要小心不要踩到自己.我将用我个人遇到过的例子进行说明.
子类化以故意覆盖属性
在这种情况下,就像Joe提到的那样,在覆盖属性之前,您最好确切地知道自己在做什么并且没有其他选项.我个人发现,通过覆盖现有属性的单个setter或getter来实现自定义通常就足够了,而不是重新声明和合成属性.例如,考虑一个专门的UIView子类,它只对具有UIClearColor背景有意义.要强制执行此操作,您可以覆盖-setBackgroundColor:以仅打印警告消息,然后不调用super的实现.我会说我从来没有理由完全覆盖一个属性,但我不会说它在某些你需要完全劫持现有属性的情况下不会是一个有用的工具.
私有财产
这比你给它的功劳更有用.私有财产的替代方案是普通的'ivar',我们都熟悉它.如果这是一个以某种频率发生变化的ivar,你最终会看到如下代码块:
[_myIvar release], _myIvar = nil;
Run Code Online (Sandbox Code Playgroud)
要么:
[_myIvar release];
_myIvar = [someValue retain];
Run Code Online (Sandbox Code Playgroud)
虽然它看起来并不太糟糕,但像这样的内存管理样板代码变得非常老,非常快.或者,我们可以将上面的示例实现为具有retain语义的私有属性.这意味着,无论如何,我们只需要:
self.myIvar = someValue;
Run Code Online (Sandbox Code Playgroud)
一段时间后,眼睛和手指更容易.你注意到这一点是正确的,因为这个属性对于宇宙的其余部分是不可见的,它可能会被子类意外地覆盖.在Objective-C中进行开发时,这是一个固有的风险,但您可以采取措施使风险小到很小.这些度量是以可预测的方式修改私有属性名称的变体.你可以在这里采取无限的道路:例如,你可以制定个人政策,在你的私人财产名称前加上你的姓名首字母和下划线.对我来说,我会得到类似的mw_ivar,相应的-setMW_ivar:和-mw_ivar访问者.是的,从统计上来说,有人可能会出现并意外地覆盖该名称,但实际上,他们不会.特别是如果您有办法将您的实践发布给可能使用您的代码的人.并且,我可以肯定地说,苹果公司并没有走出去,并且以这种方式制造了被破坏的私有财产,所以你也会在这方面保持安全.
Publicly Readonly,Privately Readwrite
这只是标准做法.你是对的,它是有用的,而且它也没有危险,因为属性在标题中.任何人意外地压倒它都只能归咎于自己.
| 归档时间: |
|
| 查看次数: |
8372 次 |
| 最近记录: |