7

我正在编写一个仅使用@properties 的应用程序。我的任何类文件中都没有声明一个 ivar。据我了解,随着@property 的引入,不再需要 ivars。我是否根据最佳实践进行编码?从长远来看,这最终会在众所周知的屁股上咬我吗?我一直在阅读关于什么是“正确”和“错误”的混合评论......

4

4 回答 4

15

并不是不需要实例变量。只是不需要实例变量声明。给定一个属性和一个@synthesize 语句,编译器将负责创建实例变量以及适当的访问器方法。

只使用属性没有错。它们简化了内存管理。如果你想要的话,使用没有属性的 iVar 也没有什么问题。如果您想使用属性但不想向世界其他地方宣传访问器(即维护封装),请考虑在类扩展中声明您的非公共属性(基本上是您的实现文件中的匿名类别)。

于 2012-01-25T21:39:11.333 回答
11

我通常也不声明 ivars。 当我的意思是通过方法时,我经常使用@synthesize foo = foo_;though来防止直接访问,反之亦然。而且我总是让编译器自动合成带有前缀的 ivar (根据敲击的短语_,这可以防止意外的直接访问)。

而且,正如 Caleb 所说,仍然有 ivars 浮动,除非你真的想要,否则你不会明确声明它们(实际上,你不会因为标题中暴露的 ivars 对类的客户没有用,如果您的 API 设计得当)。

我还发现“只在 init/dealloc 中使用直接访问,在其他地方使用 setter/getter”的炒作在很大程度上被夸大了,因此,在任何地方都使用 setter/getter。现实情况是,如果您在初始化/释放期间有观察者,那么您已经被水洗了;根据定义,对象的状态在构造/销毁期间是未定义的,因此,观察者可能无法正确推理状态。


正如 Caleb 指出的那样,在 init/dealloc 中使用直接 ivar 访问的另一个原因是避免实现自定义 setter/getter 逻辑的子类,因为在 init/dealloc 期间对象的未定义状态可能会出错。

虽然这可能是真的,但我认为使用自定义行为实现 setter/getter 是一个令人讨厌的架构缺陷。这样做很脆弱,并且随着时间的推移重构代码变得更加困难。同样,这种自定义行为通常会依赖于对象中的其他状态,然后这种依赖会导致对状态更改的顺序依赖,而这些似乎根本没有反映在看似简单的@property声明中。

即,如果您的 setter 和 getter 被编写为foo.bar = bad;无法在任何时候执行foo,那么您的代码将被破坏。

于 2012-01-25T21:40:49.260 回答
2

使用 iVars 当然没有错,但是现在的最佳实践确实推动使用 @property。

于 2012-01-25T21:38:31.920 回答
0

您可能想要使用 ivar 的一个地方是当您想要声明一个受保护的属性时。您在 .m 文件中为类声明属性,并在 .h 中使用 @protected 指令声明其对应的 ivar。然后,这将使您在子类中具有受保护的访问权限。对成员的受保护访问别无选择。

于 2013-12-19T18:35:58.383 回答