Objective-C中的getter与setter

先从传统的方式谈起

  1. .h中定义类成员变量
  2. get、set方法
  3. .m中实现get、set方法

例如,定义一个LFPerson 类,头文件LFPerson.h如下:

  

 1 #import <Foundation/Foundation.h>
 2 
 3 @interface LFPerson : NSObject{
 4   /**
 5   * 这边的成员变量都命名 _xxx
 6   */
 7    NSString *_userName;
 8    int _age;
 9 }
10 /**
11 * get方法与变量名相同(去掉_)
12 *
13 * @return 成员变量
14 */
15 -(NSString *)userName;
16 /**
17 * set 按照java的写法即可
18 *
19 * @param userName 调用set方法时传过来的参数
20 */
21 -(void)setUserName:(NSString *)userName;
22 
23 -(int)age;
24 -(void)setAge:(int)age;
25 
26 @end

 LFPerson.m文件如下:

 1 #import "LFPerson.h"
 2 
 3 @implementation LFPerson
 4 
 5 -(NSString *)userName{
 6     return _userName;
 7 }
 8 -(void)setUserName:(NSString *)userName{
 9     _userName=userName;
10 }
11 
12 
13 -(int)age{
14     if(_age > 0 && _age< 100){
15          return _age;
16     }
17     return -1;
18 }
19 -(void)setAge:(int)age{
20     if(age <= 0){
21         _age = MAXFLOAT;
22         return;
23     }
24     _age=age;
25 }
26 
27 @end

mian函数测试代码:

 1 #import <Foundation/Foundation.h>
 2 #import "LFPerson.h"
 3 
 4 int main(int argc, const char * argv[])
 5 {
 6 
 7     @autoreleasepool {
 8         
 9         LFPerson *person = [[LFPerson alloc]init];
10         
11         [person setUserName:@"afei"];
12         NSLog(@"%@", [person userName]);
13         
14         [person setAge:22];
15         NSLog(@"%d",[person age]);
16         NSLog(@"%d",person.age);//相当于[person age],即调用get方法
17 18 } 19 return 0; 20 }

测试结果如下:

 

每次要为一个属性写上getter和setter,其实是十分麻烦的,所以苹果为OC引入了@property,用来改进setter和getter

利用@property特性,改进后的LFPerson.h

1 #import <Foundation/Foundation.h>
2 
3 @interface LFPerson : NSObject
4 
5 @property(nonatomic,copy,getter = getUserName) NSString *name;
6 @property(nonatomic,assign) int age;
7 @property(nonatomic,assign) int height;
8 
9 @end

改进后的LFPerson.m

1 #import "LFPerson.h"
2 
3 @implementation LFPerson
4 
5 @end

可以看到,LFPerson.m已经很干净清爽了!这正是@property自动生成get、set带来的方便之处。

mian函数:

 1 #import <Foundation/Foundation.h>
 2 #import "LFPerson.h"
 3 
 4 int main(int argc, const char * argv[])
 5 {
 6 
 7     @autoreleasepool {
 8         
 9         LFPerson *person = [[LFPerson alloc]init];
10         
11         [person setName:@"afei"];//调用set方法,编译器自动生成
12         NSLog(@"%@", [person getUserName]);//调用get方法,@property中指定为getter为getUseNname
13         
14         person.age = 22;//.语法调用set方法
15         NSLog(@"%d",[person age]);//调用get方法,编译器自动生成,方法名与属性名相同,注意与调用setName的不同,这是apple的命名规则
16         
17         person.height = 170;
18         NSLog(@"height:%d",person.height);
19         
20     }
21     return 0;
22 }

main函数测试结果:

 

重写@property中自动生成的set、get方法

LFPerson.h

1 #import <Foundation/Foundation.h>
2 
3 @interface LFPerson : NSObject
4 
5 @property(nonatomic,copy,getter = getUserName) NSString *name;
6 @property(nonatomic,assign) int age;
7 @property(nonatomic,assign) int height;
8 
9 @end

LFPerson.m中,需要重写set、get方法

 1 #import "LFPerson.h"
 2 
 3 @interface LFPerson ()
 4 
 5 @end
 6 
 7 @implementation LFPerson
 8 
 9 @synthesize age = _age;//同时重写set、get方法就需要写@synthesize xxx = _xxx
10 //@synthesize name = _name;
11 @synthesize height = HH;
12 
13 /**
14  *  重写getter方法,并且getter方法名字是在@property中指定好的,这里只重写get方法,所以可以不用指定@synthesize
15  *
16  *  @return 返回字段
17  */
18 -(NSString *)getUserName{
19     NSString *tmp = [[NSString alloc]initWithFormat:@"the "];
20     return [tmp stringByAppendingString:_name];
21 }
22 
23 
24 /**
25  *  重写get方法,默认的get方法与变量名相同
26  *
27  *  @return 实际age+10
28  */
29 
30 -(int) age{
31     return _age+10;
32 }
33 
34 -(void)setAge:(int)age{
35     _age = age+80;
36 }
37 
38 -(void)setHeight:(int) height{
39     HH = height+10;//因为写了 @synthesize height = HH; 所以成员变量名就是HH了,不写的话,成员变量默认就是 _height了
40 }
41 -(int)height{
42     return  HH+1;
43 }
44 
45 @end

mian函数

 1 #import <Foundation/Foundation.h>
 2 #import "LFPerson.h"
 3 
 4 int main(int argc, const char * argv[])
 5 {
 6 
 7     @autoreleasepool {
 8         
 9         LFPerson *person = [[LFPerson alloc]init];
10         
11         [person setName:@"afei"];
12         NSLog(@"%@", person.name);
13         
14         [person setAge:22];
15         NSLog(@"%d",[person age]);
16         
17         person.height = 170;
18         NSLog(@"height:%d",person.height);
19         
20     }
21     return 0;
22 }

main函数测试结果如下:

在这里我说明一下@synthesize的作用:

         1、一个作用就是让编译器为你自动生成setter与getter方法 

         2、可以指定与属性对应的实例变量,如@synthesize height = HH(如果.m文件中写了@synthesize str = xxx;那么生成的实例变量就是xxx;如果没写@synthesize str;那么生成的实例变量就是_str)

         3、从xcode 4.5及以后的版本中,@property独揽了@property和@synthesize的功能。

       @property (nonatomic, copy) NSString *str;这句话完成了3个功能:

        1)     生成_str成员变量的get和set方法的声明

    2)     生成_str成员变量set和get方法的实现

    3)     生成一个_str的成员变量。(注意:这种方式生成的成员变量是private的)

总结:属性重写settergetter方法

使用属性@property能够帮我们省去了很多繁杂的工作,但有的时候我们在使用属性的时候还是需要去重写一下其setter和getter方法,这个时候我们应该怎么做呢?

  • 如果只重写settergetter其中之一

可以直接重写

  •  如果同时重写settergetter

需要加上@synthesize propertyName = _propertyName;不然系统会不认_str。因为如果你同时重写了getter和setter方法,系统就不会帮你自动生成这个_str变量,所以当然报错说不认识这个变量。所以得手动指定成员变量,然后再同时重写了getter和setter方法。

 

posted @ 2015-10-27 12:27  烫烫烫烫  阅读(1042)  评论(0编辑  收藏  举报