美文网首页
OC中self.a和_a的访问的区别

OC中self.a和_a的访问的区别

作者: 乡水情缘 | 来源:发表于2017-11-27 12:57 被阅读22次

    本文主要涉及以下几个方面

    1.@property(nonamic,assign) int age; 都做了哪些事情
    2.self.a 和 _a之间的区别
    3.实际举例说明

    第一:@property(nonamic,assign) int age; 都做了哪些事情

    (1)系统自动生成和实现setter/getter方法
    (2)系统会生成一个_age的成员变量

    第二:self.a与_a之间的区别

    首先使用self.a会调用getter/setter方法,而_a并不会调用getter/setter方法,它是直接访问实例变量并赋值。

    第三:举例说明

    下面我们通过@property的copy属性举例说明:

    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, copy) NSString *sex;
    
    - (void)changeNameValue:(NSString *)newName andChangeSexValue:(NSString *)sexValue;
    
    @end
    

    上面是一个Person类,里面有两个成员变量name和sex,声明了一个实例方法changeNameValue:andChangeSexValue:,下面实例方法的实现:

    #import "Person.h"
    
    @implementation Person
    
    - (void)changeNameValue:(NSString *)newName andChangeSexValue:(NSString *)sexValue
    {
        self.name = newName;
        _sex = sexValue;
    }
    
    @end
    

    然后在viewDidLoad方法中调用:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        NSMutableString *newName =[NSMutableString stringWithString:@"TongRy"];
        NSMutableString *newSex = [NSMutableString stringWithString:@"man"];
    
        Person *xiaoming = [[Person alloc] init];
        [xiaoming changeNameValue:newName andChangeSexValue:newSex];
    
        NSLog(@"xiaoming newName: %@, newSex: %@;", xiaoming.name, xiaoming.sex);
    
        [newName appendString:@"Good"];
        [newSex appendString:@"andwoman"];
        NSLog(@"To observe the changes : xiaoming name: %@, sex: %@;", xiaoming.name, xiaoming.sex);
    
    }
    
    • (void)viewDidLoad {
      [super viewDidLoad];

      NSMutableString *newName =[NSMutableString stringWithString:@"TongRy"];
      NSMutableString *newSex = [NSMutableString stringWithString:@"man"];

      Person *xiaoming = [[Person alloc] init];
      [xiaoming changeNameValue:newName andChangeSexValue:newSex];

      NSLog(@"xiaoming newName: %@, newSex: %@;", xiaoming.name, xiaoming.sex);

      [newName appendString:@"Good"];
      [newSex appendString:@"andwoman"];
      NSLog(@"To observe the changes : xiaoming name: %@, sex: %@;", xiaoming.name, xiaoming.sex);

    }
    运行后得到的结果:


    1210923-6f03af0f5214106b.png

    我们可以看到,newName和newSex改变了,name的值仍然没有变是TongRy,而sex的值确是改变了,末尾增加了“andwoman”.

    实际上我们期待的是对类属性的赋值是深拷贝赋值(我们声明了@property的copy属性),但是实际得到的结果是name进行了深拷贝,而sex仍然是浅拷贝。究其原因,就是因为name是self访问,sex是_访问。在调用self的时候,如果是赋值,那么编译器会自动根据strong/copy生成对应的setter方法,其实现类似于:

    //声明为copy属性时
    - (void)setName:(NSString *)name
    {
        if (_name != name)
        {
            [_name release];
            _name = [name copy];
        }
    }
    
    //当声明为retain属性时(MRC下)
    - (void)setName:(NSString *)name
    {
        if (_name != name)
        {
            [_name release];
            [name retain];
            _name = name;
        }
    }
    

    在上面的例子中,使用self.name赋值后,name已经和newName没有指向同一块内存,所以name没有随着newName值的改变而改变。_sex赋值是直接指向了newSex所指向的内存块,也没有做retain操作,容易出现问题。所以,我们在类中应该尽量使用self.a的形式来访问属性。

    用self.name 是更好的选择,因为这样可以兼容懒加载,同时也避免了使用下划线的时候忽视了self这个指针,后者容易在block中造成循环引用。同时,使用_是获取不到父类的属性,因为它只是对局部变量的访问。

    欢迎更多开发者加qq 556120515 群进来交流

    相关文章

      网友评论

          本文标题:OC中self.a和_a的访问的区别

          本文链接:https://www.haomeiwen.com/subject/caorbxtx.html