OC get set 方法理解

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; 

}

后者会覆盖前者的方法实现

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,933评论 8 265
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 13,871评论 1 32
  • 我是一张兢兢业业的床,谁关心过我的感受! / 1 / 我是王宝强家的床! 6年了,6年了…… 作为一张床,我备受折...
    肥鱼胡说阅读 2,656评论 0 0
  • 五月: 收到你的来信很开心,我已仔细读过,对你很是挂念。我想,即使时间再变,即使我俩都已老态,不复青春容颜,...
    偶然之音阅读 1,387评论 0 0
  • 思念已成往事, 愿我每日每日都会 远离思念之苦。 你在他乡, 我在我家, 多么遥远我心牵挂, 你若安好, 我不去打...
    芸暄阅读 1,846评论 0 1

友情链接更多精彩内容