OC中Property私有属性和私有变量的区别
属性是OC中类的成员变量声明的一种方法,与其对应的有Set(写)方法Get(读)方法,由于OC中对private这个概念并不常用,所以如何声明私有变量分为两种情况
与其它语言一样声明私有变量的情况
该方法是在.m中声明一个无分类名称的分类,然后在其Class Continue(类后续?)中声明私有变量,该变量并不会自动生成Get/Set方法
1 | @interface className ()<> |
声明为私有属性
在.m的无分类名称的累声明中使用@property声明成属性,因为.m是外界无法访问的,所以让其中属性成为了私有属性
1 | @interface className ()<> |
私有属性和私有变量的调用方式不同
两种不同的声明方式带来的最直接不同就是调用方法不一样
1 | //.m |
为什么私有属性通过”_”调用
私有属性需要通过下划线调用是因为@synthesize命令会自动让.m中的私有属性声明一个名字前加入下划线的指针指向实际内存,类似于C++中的this指针
@synthesize label = _label;
为什么不能通过self.调用
因为**self.label = [[UILabel alloc]init]**会因为”.”的存在去调用label的get方法
什么是Get/Set方法
属性之所以与普通变量不同,是因为每一个属性都应该有对应的Set和Get方法,可以截获属性读写时的处理。
Set方法会自动命名为**- (void)setXXX名字并且传入一个同类变量,例如上文的Label,Set函数如果不重写,就会执行_XXX=XXX**
1 | - (void)SetLabel:(UILabel)label { |
Get方法则自动命名为- (className *)XXX**,并且返回自己,如果不重写Get,就会执行return XXX**
1 | - (UILabel *)label { |
所以说我们可以通过重写以上方法,从而截获属性读写时执行的代码
所以说Synthesis/Get/Set他们到底对属性Property干了什么
每当声明一个属性时,系统会自动执行@synthesis(Xcode5之前不会)声明一个指针,指针名为下划线+属性名指向实际内存,然后当对属性进行赋值操作和读取操作时,让该下划线指针指向另外一个内存,从而让该类对的属性具有某值,或者返回该指针指向的内存让外界可以读取到该值。
赋值和读取方法都包括两种
1 | //通过方法进行Get/Set |
什么情况需要写@synthsize
如果同时重写了某个属性的Get和Set方法,系统不知道在Get和Set时具体发生了什么,所以必须手动重写@synthesize让下划线指针指向属性
另一种情况如果有readonly的属性, 那么按照定义该方法不应该具有Set方法仅仅具有Get方法,如果此时恰好有需求重写了Get方法,就需要手动写@synthesize
为什么属性这么麻烦,我还是只用私有变量好了,不用私有属性
只用私有变量也会带来未知的风险,因为私有变量在.m不用通过_来调用,万一出现了局部变量和私有变量重名的情况,就会Crash
1 | { |
卧槽这么麻烦我都要杀人了,还有什么大坑么
OC中推荐是使用属性而不是变量,所以说在使用变量的过程中就会牵扯到重写Set/Get的时候。那么在这两个方法的内部,是不可以互相调用的
例如以下,如果在Set中调用Get,那么Get应该去取_label实际指向的内存,而Set方法过程中_label实际指向的内存地址还没有确定,所以会取到一种异常状态,产生Crash。
1 | - (void)setLabel:(UILabel)label { |