Objective-C2.0中的属性是否需要声明相应的实例变量?例如,我习惯于这样做:
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
这还有效吗?它与我之前的例子有什么不同吗?
发布于 2010-06-19 12:26:31
如果您使用的是现代Objective-C运行时(即iOS 3.x或更高版本,或者64位雪豹或更高版本),那么在这种情况下,您不需要为您的属性定义ivar。
当您@synthesize
属性时,ivar实际上也将为您合成。这就绕过了"fragile-ivar“场景。你可以在Cocoa with Love上阅读更多关于它的内容
发布于 2011-02-02 13:22:59
在您的接口中,您可以在大括号之间正式声明实例变量,或者通过大括号外的@property
声明实例变量,或者两者兼而有之。无论哪种方式,它们都会成为类的属性。不同之处在于,如果您声明@property
,那么您可以使用@synthesize
实现,它会自动为您编写getter/setter代码。例如,自动编码器设置器初始化整数并将浮点数设置为零。如果您声明了一个实例变量,但没有指定相应的@property
,那么您就不能使用@synthesize
,而必须编写您自己的getter/setter。
您总是可以通过指定自己的getter/setter来覆盖自动编码的getter/setter。这通常是使用延迟加载的managedObjectContext
属性完成的。因此,您需要将managedObjectContext
声明为一个属性,然后还要编写一个-(NSManagedObjectContext *)managedObjectContext
方法。回想一下,与实例变量/属性同名的方法是"getter“方法。
@property
声明方法还允许您使用其他选项,如retain
和readonly
,而实例变量声明方法不支持这些选项。基本上,ivar
是旧的方式,@property
对其进行了扩展,并使其更花哨/更容易。你可以使用self来引用这两种方法。前缀或非前缀,只要名称对于该类是唯一的就无关紧要了。否则,如果您的超类具有与您相同的属性名称,那么您必须说like self.name或super.name,以便指定您正在讨论的名称。
因此,您将看到越来越少的人在大括号之间声明ivar
,而是转向只指定@property
,然后执行@synthesize
。如果没有相应的@property
,就不能在实现中执行@synthesize
。合成器只从@property
规范中知道它是什么类型的属性。synthesize语句还允许您重命名属性,以便您可以在代码中使用一个名称(速记)来引用属性,而在.h文件中使用全名。然而,有了XCode现在拥有的非常酷的自动补全功能,这并不是一个优势,但它仍然存在。
希望这有助于澄清所有的困惑和错误的信息,到处都是。
发布于 2011-04-13 11:04:18
这两种方法都有效,但是如果不在花括号中声明它们,就不会在xcode的调试器中看到它们的值。
https://stackoverflow.com/questions/3074248
复制相似问题