OC get set 方法理解 get set方法不能同时重写
最近在了解oc的属性,oc的属性组成是由成员变量+set/get方法组成,我们都知道用@property 声明的属性 Xcode 会帮我们生成get set 方法,有时我们根据实际需要会重写get 或者set 方法.都是可以的.但是我们get set 方法都重写,就会报错
解决方法:21行添加@synthesize name =_name;声明 下划线属性原因是: @property 已经帮我们重写了get set 方法 ,而现在我们又全部重写了get set 方法.导致Xcode 认为我们写的这 get set 方法的属性和@propery 声明的属性不是同一个属性了,所以会报错. 类似于 @property (nonatomic) NSString * name; 依然是Xcode 帮写get set 方法,但是 自己写的 get set 方法没有对应的属性声明.简而言之就是因为当你复写了get和set方法之后@property默认生成的@synthesize就不会起作用了,这也就意味着你的类不会自动生成出来实例变量了,你就必须要自己声明实例变量
如果非要重写get set 两个方法
上图中第14行代码 就是@synthesize 的作用 起到一个声明 下划线属性的作用 但是 getset 方法是我们自己实现的如上图
加一个第 14 行代码的声明. 表示我们自己声明一个属性,但是没事get set方法 需要自己重写
这样一来第16行 代码可有可无.
若 没有第16行 就类似c++ 一样了.无法突出oc 特性
加了第16 行代码 就有真正OC语言的特性,一见到@property 就知道有get set 方法
当没有第16行代码,我们又重写了get 和set 方法,这个属性的get set 方法是我们自己实现
但是同时又有第16 行代码 ,Xcode 会处理发现 @property 和我们自己声明的东西是同一个属性,我们声明的get set 方法 会覆盖Xcode生成的get set 方法
这里面又涉及到两个属性@synthesize 和 @dynamic
iOS 6 之后 LLVM 编译器引入property autosynthesis,即属性自动合成。换句话说,就是编译器会为每个 @property 添加 @synthesize ,如以下形式:
@synthesize propertyName = _propertyName;
这行代码会创造一个带下划线前缀的实例变量名,同时使用这个属性生成getter 和 setter 方法。
使用@synthesize 只有一个目的——给实例变量起个别名,或者说为同一个变量添加两个名字。
如果要阻止自动合成,记得使用 @dynamic 。经典的使用场景是你知道已经在某处实现了getter/setter 方法,而编译器不知道的情况。
此处我的理解是为了防止编译器使用自动合成生成新的setter/getter 会覆盖已经存在的旧的 setter/getter。
自动合成没有任何内存的含义,所以它根本没有连接到ARC。
如果你已经手动实现了 setter/getter方法,或着对 只读对象 实现了getter方法,那么自动合成不会产生任何影响。如果你在手动实现需要一个变量,只需声明它就可以了,不需要添加@synthesize来添加一个别名(尽管可以)。
还有一种情形需要使用 @synthesize ,就是当在 protocol 代理 中声明并实现属性时。协议中声明的属性不会自动生成setter和getter,
总结
1.@synthesize 的作用:是为属性添加一个实例变量名,或者说别名。同时会为该属性生成 setter/getter 方法。
2.禁止@synthesize:如果某属性已经在某处实现了自己的 setter/getter ,可以使用 @dynamic 来阻止 @synthesize 自动生成新的 setter/getter
3.内存管理:@synthesize 和 ARC 无关。
4.使用:一般情况下无需对属性添加 @synthesize ,但一些特殊情形仍然需要,例如protocol中声明的属性。
这种情况下编译是没有错的,但是run 一下就会出错,
@dynamic name;
禁止生成 get set 方法了
如果我们把上图的注释放开,run 一下也是正常的.
@property (nonatomic) NSString * name;
等同于
{
NSString * _name;
}
-(void)setName:(NSString *)name {
_name = name;
}
-(NSString*)name {
return _name;
}
后者会覆盖前者的方法实现
网友评论