Objective-C:@property声明没有实现(@synthesize)

8
就我所了解的情况,@property 在.h文件中声明getter和setter方法,而@synthesize 在.m文件中实现这些方法。此外,你还可以编写自己的getter和setter方法来替代使用@synthesize。
既然我们总是需要实现setter/getter方法,为什么还需要额外声明呢?在我的看法中,@property 似乎是语义上的冗余,也是产生错误的源头。
如果我声明了一个@property,但忘记用@synthesize或手动实现它,会发生什么?如果我使用@synthesize却忘记了@property声明,会发生什么呢?
4个回答

26

从Xcode 4.4开始,默认情况下会合成属性,因此您是正确的,@property和@synthesize同时写是多余的,现在只需使用@property即可。


很好他们加入了这个。感谢您的回复。 - Stefan Arn
8
仍有一种情况需要同时使用property和synthesize。编译器将使用属性名加下划线前缀创建ivar。如果变量_ivar与私有实例变量冲突,则需要将其合成为新的ivar。例如:如果你正在子类化UIToolbar,并声明一个名为delegate的属性,当尝试使用_ivar_delegate时,将会出现错误,因为UIToolbar包含一个私有实例变量id _delegate。你可以通过使用@synthesize delegate = _mydelegate;来解决这个问题。 - lolol

6
在.h文件中含有以下内容:
@property (retain, nonatomic) NSString* userName;

是一种语法糖,用于

-(NSString*)userName;

-(void)setUserName:(NSString*)userName;

在 .h 文件中,@property 用于声明属性,而在 .m 文件中的 @synthesize 则是一种语法糖,遵循你在属性声明中指定的 retain、nonatomic 等设置,使其自行实现。即使你在 .h 文件中指定了适当的 getter 和 setter,也无法合成属性而不使用 @property。
但你可以保留 @synthesize 并实现自己的 getter 和 setter。如果同时保留了 @synthesize 和自定义的 getter/setter,在运行时将优先使用你的实现。

4
当我声明一个@property却忘记使用@synthesize或手动实现它时会发生什么?当我使用@synthesize并忘记@property声明时会发生什么?
您为什么不试一试呢?如果您忘记合成访问器或自己提供访问器,编译器将发出警告。 (如果您将其设置为将警告视为错误(这是个好主意),那么不可能错过警告。)第二种情况通常会导致编译错误。
所以,如果我们总是需要实现setter/getter,为什么还需要额外声明呢?对我来说,@property似乎是语义上的冗余和bug来源。
简单地说,@property是属性声明,@synthesize是一种可能的实现方式。一个属于头文件(=公共接口描述),另一个属于实现文件。如果不是这样,您会怎么做呢?

2

我想补充一下,除了使用@synthesize,你还可以使用@dynamic。不过,这并不是你经常需要做的事情。@dynamic基本上告诉编译器,在运行时你会以某种方式确保getter和setter方法的调用得到处理,你可以自己实现它们,或者通过使用Objective C runtime的一些特殊功能进行额外的操作。


我对那个“某种程度上”很感兴趣。我想用字典来支持一些点样式属性,但是失败了。可能需要提出问题。 - Rhythmic Fistman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接