OC中self.xxx和_xxx访问的区别,深拷贝和浅拷贝的区别

    初学iOS时候,发现有的代码通过self.xxx访问,有时通过_xxx访问,一直搞不清楚有什么区别。其实,通过self.xxx是对属性进行访问,本质是调用属性的setter方法,引用计数器会+1;_xxx是直接对成员变量进行访问,是对指针的赋值,引用计数器没发生改变。下面,通过代码来看一下。

    定义属性:

@property (nonatomic, copy)NSString *strCopy1;

@property (nonatomic, copy)NSString *strCopy2;

    生成个可变字符串str,内容为“123”,分别通过self.strCopy1、_strCopy2进行赋值,通过打印,发现都能够成功赋值;

    然后对这个可变字符串str,进行拼接,内容为“123456”;

    再打印self.strCopy1和self.strCopy2,咱们这里原意应该是self.strCopy1和self.strCopy2的值不变,依然为“123”,但是,这里打印结果strCopy1正常为“123”,而strCopy2为“123456”。究竟是为什么?

- (void)viewDidLoad {

    [super viewDidLoad];  

    NSMutableString *str = [NSMutableString stringWithFormat:@"123"];

    self.strCopy1 = str;

    _strCopy2 = str;

    

    NSLog(@"strCopy1:%@ -------- strCopy2:%@",self.strCopy1,self.strCopy2 );

    //    打印出来: strCopy1:123 -------- strCopy2:123

    

    [str appendString:@"456"];

    

    NSLog(@"strCopy1:%@ -------- strCopy2:%@",self.strCopy1,self.strCopy2 );

    //    打印出来: strCopy1:123 -------- strCopy2:123456

}

    因为通过self.strCopy1赋值是调用了编译器默认生成的setter方法,调用了[_strCopy1 copy],copy为内容拷贝,就是深拷贝,_strCopy1已经指向了重新生成的另一块内存了,不是原来_str指向的那一块内存了,所以改变_str原来指向的那块内存里面的字符串内容,不影响_strCopy1指向的内容。

    而通过_strCopy2赋值,是对成员变量直接赋值,没有进行内容拷贝(深拷贝),只是进行了指针拷贝(浅拷贝),_strCopy2仍然指向_str原来指向的那块内存。所以改变_str原来指向的那块内存的字符串内容,会直接影响_strCopy2的内容。 

    其实,copy和retain的区别就是深拷贝和浅拷贝的原因。也是为什么修饰NSString的是copy,而不是retain。

    

原文地址:https://www.cnblogs.com/ladyotao/p/5802586.html