每个伊娃都必须是财产吗?

Die*_*ego 56 properties objective-c instance-variables ios

我看到它在为iOS编码时建议应该使用属性来访问实例变量,因为这会给内存管理带来诸多好处.

这个建议并不适合我.我发现使用属性而不是普通的旧ivars只需要太多的代码,如果你对内存管理感到满意,我并没有真正看到它的好处.它真的那么重要吗?您管理实例变量的方法是什么?

Dan*_*son 78

没有必要为所有ivars声明属性.想到几点:

  • 如果ivar仅在对象的生命周期中被分配一次,那么通过声明属性你并没有真正获得任何东西.只需保留/复制/分配期间init,然后在必要时释放dealloc.
  • 如果要经常更改ivar,声明属性并始终使用访问器将更容易避免内存管理错误.
  • 如果属性和ivars是私有的,则可以在.m文件而不是.h文件中的类扩展中声明属性.
  • 在定位iOS 4.0+时,如果定义属性并合成访问者,则无需在标题中声明ivars.

所以我通常使用属性,但是对于像NSMutableArray对象分配的那些东西init并用于容纳一堆whatevers,我将使用一个普通的旧ivar,因为我永远不会重新分配ivar.

  • 如果我有一个NSMutableArray作为实例变量,我通常会故意不为它定义一个属性**.这是因为,如果将其作为可变数组传递给另一个对象,则该另一个对象可以在不告知第一个对象的情况下有效地修改第一个对象的内部状态.这破坏了封装. (11认同)

bbu*_*bum 51

虽然丹尼尔的答案是正确的,但我认为它错过了一个重要的观点.即:

我发现使用属性而不是普通的旧ivars只需要太多的代码,如果你对内存管理感到满意,我并没有真正看到它的好处.

好处是一致性; 一致的内存管理和一致的行为.

值得注意的是,这两行代码在运行时实际上可能具有极其不同的行为:

iVar = [foo retain];
self.iVar = foo;
Run Code Online (Sandbox Code Playgroud)

第一个是实例变量的直接设置,不会有更改通知.第二个遍历setter,因此,在设置时保留任何子类自定义,确保向属性的任何观察者通知更改.

如果您在整个代码中直接使用ivars(在类的内部 - 如果您直接从该实例外部使用实例的ivars,那么......任何在您的代码库上工作的承包商应该加倍他们的费率;),那么你必须或者也可以手动处理更改通知传播(通常通过调用willChangeValueForKey:/ didChangeValueForKey)明确设计应用程序以避免使用依赖于键值观察的机制.

你说"需要太多代码".我没有看到; 在上面两行代码中,点语法是较少的字符.即使使用传统语法调用setter方法也会减少代码.

并且不要忽视集中内存管理的价值; 在无数的呼叫站点和崩溃的城市中发生了一次意外遗漏.

  • 如果人们将来来到这里并错过了周围的评论,那么在iOS 4中,如果申报房产,则无需申报ivar.这涉及迭戈在这里讨论的很多问题. (8认同)
  • 使用iOS 5中的ARC(和4,带有警告),您也不必声明`dealloc`. (4认同)
  • @MattDiPasquale这是一个品味问题; 我有时在`@ implementation`中声明ivars并且只直接使用它们.有时我会在.m文件顶部的类扩展中声明`@ property`s.有点不一致,真的.我在`init`之外使用`self.foo =`(在MRR中使用`dealloc`).我在`init`中使用`_foo =`. (2认同)