做声明的属性需要一个相应的实例variables?

Objective-C 2.0中的属性是否需要声明相应的实例variables? 例如,我习惯于这样做:

MyObject.h

@interface MyObject : NSObject { NSString *name; } @property (nonatomic, retain) NSString *name; @end 

MyObject.m

 @implementation @synthesize name; @end 

但是,如果我这样做,而是:

MyObject.h

 @interface MyObject : NSObject { } @property (nonatomic, retain) NSString *name; @end 

这仍然有效吗? 和我以前的例子有什么不同吗?

如果您使用的是Modern Objective-C Runtime(即iOS 3.x或更高版本,或64位Snow Leopard或更高版本),那么在这种情况下,您无需为您的属性定义ivars。

当你合成财产时,实际上伊娃也会为你合成。 这绕过了“脆弱的伊娃”的情况。 你可以阅读关于cocoa爱的更多信息

在你的界面中,你可以在大括号之间正式声明一个实例variables,或者通过大括号之外的@property声明这两个variables。 无论哪种方式,他们成为class级的属性。 不同的是,如果你声明@property ,那么你可以使用@synthesize来实现,它会自动为你的getter / setter编码。 例如,自动编码器设置器初始化整数并浮点数为零。 如果你声明了一个实例variables,并且不指定相应的@property ,那么你不能使用@synthesize并且必须编写你自己的getter / setter。

您始终可以通过指定自己的代码来覆盖自动编码的getter / setter。 这通常是使用延迟加载的managedObjectContext属性完成的。 因此,你声明你的managedObjectContext作为一个属性,但是还要写一个-(NSManagedObjectContext *)managedObjectContext方法。 回想一下,一个与实例variables/属性名称相同的方法是“getter”方法。

@property声明方法还允许你使用实例variables声明方法不支持的其他选项,如retainreadonly 。 基本上, ivar是古老的方式, @property扩展它,使更加fancier /容易。 你可以参考使用自己。 前缀,否则,只要该名称对于该类是唯一的就没有关系。 否则,如果你的父类和你的属性名称相同,那么你必须说或者像self.name或者super.name来指定你正在谈论的名字。

因此,你会看到在大括号之间声明ivar的人越来越less,而是转向只是指定@property ,然后做@synthesize 。 没有相应的@synthesize ,你不能在你的实现中执行@synthesize 。 合成器只知道它来自@property规范的属性types。 综合语句还允许您重命名属性,以便您可以在代码中通过一个名称(简写)引用属性,但在.h文件外部使用全名。 但是,XCode现在拥有非常酷的自动完成function,这不是一个好处,但仍然存在。

希望这有助于消除所有在这里漂浮的混乱和错误信息。

它的工作原理是双向的,但是如果你不用花括号来声明它们,你将不会在xcode的debugging器中看到它们的值。

从文档:

通常,现代和旧版运行时的属性行为是相同的(请参阅“Objective-C运行时编程指南”中的“运行时版本和平台”)。 有一个关键的区别:现代运行时支持实例variables综合,而传统运行时不支持。

要使@synthesize在旧版运行时中工作,您必须提供一个具有相同名称和兼容types的实例variables,或者在@synthesize语句中指定另一个现有实例variables。 使用现代运行时,如果不提供实例variables,编译器会为您添加一个实例variables。

如果您使用XCode 4.4或更高版本,它将为您生成实例variables合成代码。

你只需要声明像下面的属性; 它会为您生成合成代码和实例variables声明代码。

 @property (nonatomic, strong) NSString *name; 

它会生成合成代码

 @synthesize name = _name; 

你可以使用_name访问实例variables,这与declare类似

 NSString* _name 

但是如果你声明只读属性就好

 @property (nonatomic, strong, readonly) NSString *name; 

它会生成代码

 @synthesize name; 

要么

 @synthesize name = name; 

所以你应该使用出现前缀“_”的方式访问即时variables名称,只要你可以编写你自己的合成代码,编译器就会为你生成代码。 你可以写

 @synthesize name = _name; 

Objective-C编程语言:属性实现指令

访问器综合的行为依赖于运行时(见“运行时差异”):

  • 对于传统运行时,实例variables必须已经在当前类的@interface块中声明。 如果存在与该属性同名的实例variables,并且其types与该属性的types兼容,则使用该variables,否则会出现编译器错误。

  • 对于现代运行时(请参阅“Objective-C运行时编程指南”中的“运行时版本和平台”),将根据需要合成实例variables。 如果同名的实例variables已经存在,则使用它。