何时使用实例变量以及何时使用属性

时间:2012-05-03 13:28:43

标签: objective-c ios cocoa instance-variables

使用Objective-C属性时,您是否可以完全停止创建实例变量,或者显式实例变量(不是属性合成的变量)仍然用于属性不合适的目的?

4 个答案:

答案 0 :(得分:13)

  

你可以完全停止创建实例变量

不,你不能(在某种意义上)。如果你有属性,你可以做的就是停止声明它们。如果您合成了一个属性但尚未声明instvar,那么它将为您声明,因此您创建的是一个实例变量,而不是显式的。

  

他们是否仍然服务于属性不合适的目的?

它曾经是为一切创建属性的建议,因为具有合成属性可以为您完成几乎所有的保留和发布。但是,使用ARC,使用属性来包装内存管理的原因已经消失。我相信,现在(对于ARC)的建议使用属性来声明外部接口,但使用直接实例变量,其中变量是对象内部状态的一部分。

这是采用ARC的一个很好的理由:属性只是作为类的API的一部分而恢复到它们的真正目的,并且不再需要将它们用作隐藏内存管理工作的hacky方式。

修改

还有一件事:您现在可以在@implementation中声明实例变量,因此现在无需泄漏@interface中的任何实现细节。即。

@implementation MyClass
{
    NSString* myString;
}
// method definitions
@end

而且我很确定它也适用于类别。 - 请参阅下面的评论

答案 1 :(得分:9)

我建议将所有内容声明为属性并完全避免使用手动ivars。手动创建ivars没有真正的好处。在标头@interface中声明公共属性,在.m文件的私有类扩展中声明私有属性。

对于JeremyP的一些观点,即使内存管理不再是一个重要问题,内部使用访问器仍然具有ARC的重要价值。它确保KVO正常工作,更好的子类,支持自定义setter(特别是像NSTimer之类的东西),支持自定义getter(例如用于延迟实例化)等等。混合使用者非常容易出错和伊娃。忘记你需要以哪种方式访问​​它太容易了。一致性是良好的ObjC的标志。

如果您出于某种原因绝对必须申报ivar,那么您应该在JeremyP注意到的@implementation区块中进行宣传。


更新(2013年10月):

Apple's guidance(来自使用Objective-C编程:封装数据):

  

大多数属性都由实例变量支持

     

通常,即使您从自己的实现中访问对象的属性,也应该使用访问器方法或点语法进行属性访问,在这种情况下,您应该使用self

     

...

     

此规则的例外情况是编写初始化,释放或自定义访问器方法时,如本节后面所述。

答案 2 :(得分:0)

此问题在here

之前得到解决

当您使用synthesize时,将为您处理和实例化实例变量。如果您使用新版XCode使用Lion,请查看ARC in Transitioning to ARC中的各种属性

答案 3 :(得分:0)

您始终可以从外部访问属性。因此,如果您只想从类中读取变量,则仍需要声明iVar。使用object->ivar访问公共ivar比使用方法调用稍快一些。