@Property
本质:@property = ivar(带下划线的实列变量) + getter/setter(存取方法);
使用@property定义属性后,编译器会自动编写访问属性所需的方法,此过程叫做“自动合成”(autosynthesis)。
这个过程由编译器在 编译期执行,所以编辑器里看不到这些“合成方法”(synthesized method)的源代码。除了生成方法代码 getter、setter 之外,编译器还要自动向类中添加适当类型的实例变量,并且在属性名前面加下划线,以此作为实例变量的名字。
系统做的事:
1. 系统会在 ivar_list 中添加一个成员变量的描述
2. 在 method_list 中增加 setter 与 getter 方法的描述
3. 在属性列表中增加一个属性的描述
4. 计算该属性在对象中的偏移量, 给出 setter 与 getter 方法对应的实现,在 setter 方法中从偏移量的位置开始赋值,在 getter 方法中从偏移量开始取值,为了能够读取正确字节数,系统对象偏移量的指针类型进行了类型强转.
如果.m 文件中:@synthesize和@dynamic我们都没写,那么系统默认的就是@syntheszie var = _var,其实在.m文件中实际是存在@synthesize声明语句的,只是系统将其隐藏了。
比如:
使用@property声明一个属性name,系统默认的就是 @synthesize name = _name;
有时候会看到 @synthesize name这种写法 ,它等同于 @synthesize name = name;
如果在.h 文件中使用@property声明一个属性,在 .m 文件中同时又重写了setter和getter的话,就会报错,因为同时重写setter和getter方法,系统就不会自动帮我们生成成员变量。需要在.m 文件中给这个属性添加上@synthesize关键字:@synthesize name = _name;
@synthesize
@synthesize修饰一个属性表示:如果在.m 文件中,我们没有手动实现setter和getter方法,编译器会自动加上这两个方法。如果找不到实例变量则编译器主动创建一个。
@synthesize obj=_obj 意义详解
意思是:为成员变量_obj起个属性名称叫obj。 这样写是为了区分成员变量_obj和属性名称obj,在.m里面使用的时候见到_objh就知道是成员变量了,见到self.obj就知道是属性了。
系统库中的所有类的声明部分都是这样写的。 为了区分成员变量名称和属性名称。
例如:
@implementation ViewController
@synthesize publicName = ffff;
如果类里没有ffff这个成员变量,它会自动帮你创建一个,并且帮你生成如下的setter和getter方法。
- (void)setPublicName:(NSString *)publicName{
ffff = publicName;
}
- (NSString *)publicName{
return ffff;
}
所以这个@synthesize,可以用来让属性和某个成员变量绑定。
@dynamic
@dynamic 告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。假如一个属性被声明为 @dynamic var,而且你没有提供 @setter方法和 @getter 方法,编译的时候没问题,但是当程序运行到 self.var = someVar,由于缺 setter 方法会导致程序崩溃;或者当运行到 someVar = var 时,由于缺 getter 方法同样会导致崩溃。
编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。
注意:@dynamic 不能像 @synthesize 那样由系统在实现文件中(.m)自动生成实例变量,所以需要我们手动在.m类中 显式定义出实例变量 _var 。
参考:
iOS 关键字 @property,@synthesize,@dynamic
网友评论