@synthesize @dynamic详解
@synthesize @dynamic
OC最初设定@property和@synthesize的作用:
1. @property的作用是定义属性,声明getter,setter方法。(注意:属性不是变量)
2. @synthesize的作用是实现属性的,如getter,setter方法。
在声明属性的情况下如果重写setter,getter,方法,就需要把未识别的变量在@synthesize中定义,把属性的存取方法作用于变量。如:.h文件中
后来因为使用@property灰常频繁,就简略了@synthesize的表达
从Xcode4.4以后@property已经独揽了@synthesize的功能主要有三个作用:
@synthesize三个作用:
- 生成了成员变量get/set方法的声明
- 生成了私有的带下划线的的成员变量因此子类不可以直接访问,但是可以通过. get/set方法访问。那么如果想让定义的成员变量让子类直接访问那么只能在.h文件. 中. 定义成员变量了,因为它默认是@protected
- 生成了get/set方法的实现
用@property声明的成员属性,相当于自动生成了setter getter方法,如果重写了set和get方法,与@property声明的成员属性就不是一个成员属性了,是另外一个实例变量,而这个实例变量需要手动声明。所以会报错误。
总结:一定要分清属性和变量的区别,不能混淆。@synthesize 声明的属性=变量。意思是,将属性的setter,getter方法,作用于这个变量。
@synthesize:自动合成
- 自动合成 getter, setter:注意名字编译器会自动检查,如果没有手动实现,会自动添加 getter,setter,如果实现了,则不做处理
- 具体合成那些其实还和 ready write 相关修饰符相关的,默认为 readwrite
- 指定变量名字:@synthesize firstName = _myFirstName;
- 合成规则:假设声明为 @property NSString *firstName;
- 变量 ivar 名字ivar 变量名称为 _firstName
- getter, setter:getter 变量名称为 firstName, setter 为 setFirstName
那些情况下自动合成会失效
- 同时重写了 setter 和 getter 时
- 重写了只读属性的 getter 时
- 使用了 @dynamic 时
- 在 @protocol 中定义的所有属性
- 在 category 中定义的所有属性
- 重载的属性
@dynamic:禁止自动合成
禁止自动合成getter, setter:告诉编译器属性的 setter 与 getter 方法由用户自己实现,不自动生成。(当然对于 readonly 的属性只需提供 getter 即可)
注意:属性被声明为 @dynamic var,然后你没有提供 @setter方法和 @getter 方法,编译的时候没问题,但是当程序运行到 instance.var = someVar,由于缺 setter 方法会导致程序崩溃; 或者当运行到 someVar = var 时,由于缺 getter 方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定
使用场景:
在CoreData的NSManagedObject类使用的某些。如果你想这些情况下,声明和使用属性,但要避免缺少方法在编译时的警告,你可以使用@dynamic动态指令,而不是@synthesize合成指令。
使用场景
- 场景1
ViewController.h |
- 场景2
ViewController.h |
- 场景3 @synthesize还可以用来自定义Property所对应的ivar的名称。例子如下:
#import <UIKit/UIKit.h> |
场景4:在protocol中声明属性
场景5 覆盖属性参考: