每个伊娃都必须是一个财产?
我发现,在为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的方法。