你提到的每种情况都有一个合适的地方,在野外使用的频率不同。你只需要小心不要踩到自己。我将用我个人遇到的例子来说明。
有意覆盖属性的子类化
在这种情况下,就像 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 并没有四处走动并制造以这种方式破坏的私有财产,因此您在这方面也很安全。
Publicly Readonly, Private Readwrite
这只是标准做法。你是对的,它很有用,而且它并不危险,因为属性在标题中。任何不小心超越它的人都只能怪自己。