@dynamic和@synthesize
@property中使用@dynamic和@synthesize有何不同呢?
@synthesize将为属性自动生成getter和setter方法。@dynamic仅告诉编译器该属性的getter和setter方法不在类本身,而在其他地方(如父类或者在运行时中提供)。
- 如果你没有手动实现 setter 方法和 getter 方法,那么编译器会自动为你加上这两个方法
- 如果 @synthesize和 @dynamic都没写,那么默认的就是@syntheszie var = _var;
有些访问器方法是在运行时动态创建的,例如CoreData的NSManagedObject类中使用的某些访问器。如果希望在这些情况中声明和使用属性,但希望避免在编译时出现方法的警告,可以使用@dynamic指令而不是@synthesize。
使用@dynamic指令本质上是告诉编译器“不要担心,方法马上会出现”,使用了动态绑定的概念。
@dynamic的用法有:NSManagedObject (CoreData)的子类,或者你想为一个超类定义的属性创建一个outlet,而这个超类没有定义为outlet。@dynamic还可以用于委托实现访问器的职责。如果您自己在类中实现访问器,那么通常不使用@dynamic。
父类:
@property (nonatomic, retain) NSButton *someButton;
...
@synthesize someButton;
子类:
@property (nonatomic, retain) IBOutlet NSButton *someButton;
...
@dynamic someButton;
自动合成(autosynthesis)
- 完成属性定义后,编译器会自动编写访问这些属性所需的方法,此过程叫做“自动合成”(autosynthesis)
- 需要强调的是,这个过程由编译器在编译期执行,所以编辑器里看不到这些“合成方法”(synthesized method)的源代码
- 除了生成方法代码 getter、setter 之外,编译器还要自动向类中添加适当类型的实例变量,并且在属性名前面加下划线,以此作为实例变量的名字。
例如
@interface Person : NSObject
@property NSString *firstName;
@property NSString *lastName;
@end
上述代码写出来的类与下面这种写法等效:
@interface Person : NSObject
- (NSString *)firstName;
- (void)setFirstName:(NSString *)firstName;
- (NSString *)lastName;
- (void)setLastName:(NSString *)lastName;
@end
- 除了生成方法代码 getter、setter 之外,编译器还要自动向类中添加适当类型的实例变量,并且在属性名前面加下划线,以此作为实例变量的名字。
- 在前例中,会生成两个实例变量,其名称分别为 _firstName 与 _lastName。
- 也可以在类的实现代码里通过 @synthesize 语法来指定实例变量的名字.
@implementation Person
@synthesize firstName = _myFirstName;
@synthesize lastName = _myLastName;
@end
参考资料
[@synthesize vs @dynamic, what are the differences?](https://stackoverflow.com/questions/1160498/synthesize-vs-dynamic-what-are-the-differences)
@synthesize 和 @dynamic 的作用