什么时候应该@synthesize
在代码中明确添加?
通常,如果需要的话:您可能永远不会遇到需要它的情况。
不过,有一种情况您可能会发现它很有用。
假设您正在编写自定义getter和setter,但希望使用实例变量来支持它。(对于原子属性,这就像需要自定义setter一样简单:如果您为单原子属性而不是原子属性指定setter,则编译器将编写getter。)
考虑一下:
@interface MyObject:NSObject
@property (copy) NSString *title;
@end
@implementation MyObject
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
@end
这将不起作用,因为_title
不存在。您已经指定了一个getter或setter,所以Xcode(正确)不会为其创建一个后备实例变量。
要使其存在,您有两种选择。您可以将更改@implementation
为此:
@implementation MyObject {
NSString *_title;
}
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
@end
或将其更改为:
@implementation MyObject
@synthesize title = _title;
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
@end
换句话说,尽管合成实际上并不是必需的*,但是当您提供一个getter / setter时,它可以用来定义支持属性的实例变量。您可以在此处决定要使用的表格。
过去,我倾向于在中指定实例变量@implementation {}
,但现在我认为@synthesize
路由是一个更好的选择,因为它删除了冗余类型,并将后备变量与属性明确关联:
- 更改属性的类型,实例变量的类型也会更改。
- 更改其存储限定符(例如,使其变弱而不是强或使它变弱而不是弱),并且存储限定符也会更改。
- 删除或重命名该属性,
@synthesize
将生成编译器错误。您最终不会遇到流浪实例变量。
*-我知道一种情况是有必要的,它涉及在多个文件中跨类别拆分功能。如果苹果修复了这个问题,甚至已经修复了,我也不会感到惊讶。