记得以前学C/C++/java时也接触过类似于类的实现问题. 只有在Java的类实现时,有一个不成文的小标准,就是需要为类中的成员变量实现一个getter和setter方法.
当时觉得就是给成员变量赋值和取值的时候更方便,更有独立性,逼格更高点,呵呵~ 所以在学习OC时也没有特别的在意,就是一目十行的瞟了一眼,以为就是那点事.
但是到了后的学习发现,貌似跟想想中的有点出入.当然了,关于IOS的学习书籍中,国内的书都是不负责的,好点的前面部分会给你讲一些基础的OC.
然后上来就给你展示一堆的控件,让你满足感瞬间爆棚.但是对于基础的语言特性几乎不讲,当你自己学代码的时候,会一头雾水.
好了说重点,上菜先.
@interface Person : NSObject{
int _age;
}
-(void) setAge: (int) age;
-(int) age;
@end
@implementation Person
-(void) setAge: (int) age{
_age = age;
}
-(int) age{
return _age;
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person * perabc = [[Person alloc] init];
perabc.age = 100;
NSLog(@"age = %d", perabc.age);
}
return 0;
}
在Java中给成员变量配setter和getter方法时只需要结果实现就行了 ,过程什么的不重要,但是在OC中这是绝对不行的.
有一些"烦人"的特性:
setter方法:
-(void) setAge: (int) age;
getter方法:
-(int) age;
修改任何一点都将导致编译不通过.
========================
补充一下, 当我们在使用"." 点语法的时候, 实际上就是在调用相应的getter 和setter方法, 当给成员赋值的时候 当然调用的就是setter 方法, 需要取值的时候当然就是getter方法
至于编译器是怎么判断的,这我们就不去深究了, 记得以前在一本C语言的书上说是什么左值 什么的,估计就是那个...
=========================
@interface Person : NSObject{
int _age;
}
property编译指令
当我们的类中成员变量 很多时候,再加上 OC中的特性,在不使用"->" 语法的时候,就必须实现很多个getter和setter方法
为了简化操作,我们通过编译指令,@property
在高版本的XCODE 中对该指令进行了 加强.较早的版本中
@property是实现getter和setter方法的定义
@synthesize是实现getter和setter方法的具体实现
较高版本中我们只需要一个@property就可以完成定义与实现
上面提到了,在使用property时候会生成一个私有的成员变量,该变量的名字是成员变量的名字前加下划线, "_成员名".
@interface Person : NSObject{
@public int ages;
}
@property (nonatomic, assign) int age;
@end
这个类中,本身的成员变量名字为ages, 我们又定义了一个 @property (nonatomic, assign) int age; 也就是又定义了一个age变量
其实一般不这样写,这是为了说明,此时 ages和age是并存的,而且还有一个property生成的 "_age"变量,只不过该变量只是在该指令所完成的setter和getter方法的内部使用
当我们重写getter和setter方法时就需要使用到,看代码
@implementation Person
-(void) setAge: (int) age{
_age = age + 10;
}
@end
这两种方法语法上都没问题, 我们在写了 "_age = age + 10;" 这条语句, 然后在main函数中 调用setter方法
Person * perabc = [[Person alloc] init];
perabc.age = 100;
NSLog(@"%d", perabc.age);
此时输出是110
然后我们修改代码
@implementation Person
-(void) setAges: (int) age{
_age = age + 100; //需要手动完成getter方法以及 修改perabc.age = 100; 为 perabc.ages = 100;
}
@end
我们现在使用setAges这个名字, 此时又会输出什么呢???
此时输出的是200
好了, 这怎么解释呢...
当我们使用setAge 的时候, 是重写了由@property所生成的setter方法
当我们使用setAges的时候, 我们是给类中的 @public int ages; 的成员变量实现setter方法
那么这一切就解释通了,也再一次强调了,我们上面提到的一系列OC中关于setter和getter方法..也就是名字的重要性.
==============================
刚才我们还提到过 " 其实一般不这样写,这是为了说明,此时 ages和age是并存的,而且还有一个property生成的 "_age"变量 "
那么通过 上面的 110 和 200 的输出结果是否也 说明了这个问题.他们确实是并存的, 只不过由于我们在代码中使用了 点语法, 而点语法的作用就是去调用setter 和getter方法
相当于进行了一次透明的封装,以及调用.我们没怎么感受到而已. 我们只需要在输出语句中不使用点语法就可以验证
在这条语句下再加一条 不适用点语法的语句
NSLog(@"%d", perabc.age); //使用setAge方法
NSLog(@"%d", perabc->ages); //使用setAge方法
因为类中定义的ages没有被赋值,只是进行了简单的初始化所以是0, 也就验证了并存性.
我还试着访问property 生成的私有_age变量, 但是无法实现,只能在重写的setter方法中使用.
在实际应用中,往往一个成员一条property语句就行了 , 然后根据需要重写相应的sette和getter方法即可
@interface Person : NSObject
@property (nonatomic, assign) int age;
@end
==============================
先写的到这,以后遇到问题再补充..