做声明的属性需要一个相应的实例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声明方法不支持的其他选项,如retain
和readonly
。 基本上, 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已经存在,则使用它。