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

我发现,在为iOS编码时,我们推荐使用这些属性来访问实例variables,因为这可以带来内存pipe理的好处。

这个build议对我来说并不是很好。 我发现使用属性而不是普通的旧ivars只需要太多的代码,如果你对内存pipe理感到满意,我不会真正看到好处。 这真的很重要吗? 你有什么办法pipe理实例variables?

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

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

所以我通常使用属性,但是像init对象在init分配的NSMutableArray类似的东西,用来存放一堆whatevers,我会用一个普通的旧伊娃,因为我永远不会重新分配伊娃。

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

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

好处是一致性; 一致的内存pipe理和一致的行为。

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

 iVar = [foo retain]; self.iVar = foo; 

第一个是实例variables的直接设置,不会有更改通知。 第二遍通过setter,从而在设置时保留所有的子类自定义, 确保任何观察者的财产被通知的变化

如果你直接在你的代码中使用ivars(在内部直接使用这个类 – 如果你直接从这个实例外部使用一个实例的ivars,那么…任何在你的代码库上工作的承包商都应该把他们的速度加倍),那么你必须也可以手动处理更改通知传播(通常通过调用willChangeValueForKey: / didChangeValueForKey显式devise您的应用程序以避免使用依赖于键值观察的机制。

你说“需要太多的代码”。 我不明白 在上面的两行代码中,点语法是较less的字符。 即使使用传统的语法来调用setter方法也会less一些代码。

不要忽视集中内存pipe理的价值; 一个意外的疏忽在无数的呼叫站点和崩溃的城市。

属性只是语法糖,避免你一遍又一遍地写同样的方法。 有一个属性,你有一个释放旧对象,并保留新的免费的二传手。

对于私有领域 – 我build议只使用原始types(BOOL / int / float等)直接使用ivars是安全的。 我发现一个很好的做法是在属性中包装与内存pipe理相关的所有内容 – 甚至是很less使用的字段。 这种方法的额外好处是,IDE通常突出显示直接ivars访问不同,所以你总是有简单的标量字段和对象types的字段很好的分离。

与此相反,我会强烈劝阻类公共接口中的任何直接ivars 。 由于语言的dynamic性,它可能导致运行时错误,这些错误极难find,本地化和修复。 考虑以下层次结构

 @interface BaseControl ... @end @interface Label : BaseControl ... @end @interface Button : BaseControl { @public BOOL enabled; } @end 

和一个代码片段

 - (void)enableAllButtons { NSArray *buttons = [self getAllButtons]; // expected to contain only Button instances for (Button *button in buttons) { button->enabled = YES; } } 

现在想象一下-getAllButtons逻辑中的某处出现错误,并且您还得到了该数组中返回的一些Label – 所以这些Label类实例将会缺lessivar分配。 可能令人惊讶的事实是,在这种情况下,allablebuttons不会崩溃。 但是在那个时候,这些Label实例的内部结构已经被破坏了 ,这导致未定义的行为,并在其他地方被使用时崩溃。

像一些stream行的内存pipe理问题(通常是悬挂指针),这类问题很难find和本地化,因为错误的出现通常远离(从时间,代码或应用程序stream)放置,导致错误。 但是有了这个特殊的问题,你甚至没有方便的工具(如泄漏/僵尸分析仪等)来帮助你本地化和修复它 – 即使你学习如何重现它,并且可以很容易地调查错误的状态。

显然,如果你使用@property (assign) BOOL enabled; 您将在-enableAllButtons中获得一个易于诊断和修复运行时exception的方法。