zoukankan      html  css  js  c++  java
  • 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方法。

  • 相关阅读:
    WPF Path和图形
    WPF学习笔记:(二)数据绑定模式与INotifyPropertyChanged接口
    WPF学习笔记:(一)数据绑定与DataContext
    IOC 的理解与解释
    WPF入门教程系列(二) 深入剖析WPF Binding的使用方法
    WPF入门教程系列(一) 创建你的第一个WPF项目
    一、什么是WPF?
    项目问题一、全局变量引起的并发问题
    常用js操作
    escape
  • 原文地址:https://www.cnblogs.com/ylfeiu/p/4913834.html
Copyright © 2011-2022 走看看