iOS 属性之 strong和copy修饰的区别

iOS 属性之 strong和copy修饰的区别

    //1.当生成一个不可变字符串,通过下划线进行赋值。
    NSString *textString =[NSString stringWithFormat:@"初始化字符串"];
    _strongtitle=textString;
    _ccopytitle=textString;
    NSLog(@"//1.当生成一个不可变字符串,通过下划线进行赋值。");

    NSLog(@"textString: %p , %p , %@", textString, &textString, textString);
    NSLog(@"_strongtitle: %p , %p , %@", _strongtitle, &_strongtitle, _strongtitle);
    NSLog(@" _ccopytitle: %p , %p , %@", _ccopytitle, &_ccopytitle, _ccopytitle);
    
    //2.当生成一个不可变字符串,通过点语法赋值。
    
    NSString *textString1 =[NSString stringWithFormat:@"初始化字符串"];
    self.strongtitleP=textString1;
    self.ccopytitleP=textString1;
    NSLog(@" //2.当生成一个不可变字符串,通过点语法赋值。");
    NSLog(@"textString1: %p , %p , %@", textString1, &textString1, textString1);
    NSLog(@"self.strongtitleP: %p , %p , %@", _strongtitleP, &_strongtitleP, _strongtitleP);
    NSLog(@"self.ccopytitleP: %p , %p , %@", _ccopytitleP, &_ccopytitleP, _ccopytitleP);
    
    //3.当生成一个可变字符串,通过下划线进行赋值。
    NSMutableString *mutabTextString =[NSMutableString stringWithFormat:@"初始化可变字符串"];
    _strongtitlePotent=mutabTextString;
    _ccopytitlePotent=mutabTextString;
    [mutabTextString setString:@"修改后字符串"];
    NSLog(@" //3.当生成一个可变字符串,通过下划线进行赋值。");

    NSLog(@"mutabTextString: %p , %p , %@", mutabTextString, &mutabTextString, mutabTextString);
    NSLog(@"_strongtitlePotent: %p , %p , %@", _strongtitlePotent, &_strongtitlePotent, _strongtitlePotent);
    NSLog(@" _ccopytitlePotent: %p , %p , %@", _ccopytitlePotent, &_ccopytitlePotent, _ccopytitlePotent);
    
    //4.当生成一个可变字符串,通过点语法赋值。
    NSMutableString *mutabTextString1 =[NSMutableString stringWithFormat:@"初始化可变字符串"];
    self.strongtitleSet=mutabTextString1;
    self.ccopytitleSet=mutabTextString1;
    [mutabTextString1 setString:@"修改后字符串"];
    NSLog(@"//4.当生成一个可变字符串,通过点语法赋值。");

    NSLog(@"mutabTextString: %p , %p , %@", mutabTextString1, &mutabTextString1, mutabTextString1);
    NSLog(@"self.strongtitleSet: %p , %p , %@", _strongtitleSet, &_strongtitleSet, _strongtitleSet);
    NSLog(@"self.ccopytitleSet: %p , %p , %@", _ccopytitleSet, &_ccopytitleSet, _ccopytitleSet);
//1.当生成一个不可变字符串,通过下划线进行赋值。
 textString: 0x282f33330 , 0x16ef11b58 , 初始化字符串
 _strongtitle: 0x282f33330 , 0x1017069b0 , 初始化字符串
 _ccopytitle: 0x282f33330 , 0x1017069b8 , 初始化字符串
  //2.当生成一个不可变字符串,通过点语法赋值。
 textString1: 0x282f32d90 , 0x16ef11b50 , 初始化字符串
self.strongtitleP: 0x282f32d90 , 0x1017069c0 , 初始化字符串
self.ccopytitleP: 0x282f32d90 , 0x1017069c8 , 初始化字符串
 //3.当生成一个可变字符串,通过下划线进行赋值。
mutabTextString: 0x282f33360 , 0x16ef11b48 , 修改后字符串
_strongtitlePotent: 0x282f33360 , 0x1017069d0 , 修改后字符串
 _ccopytitlePotent: 0x282f33360 , 0x1017069d8 , 修改后字符串
 //4.当生成一个可变字符串,通过点语法赋值。
mutabTextString: 0x282f1ccf0 , 0x16ef11b40 , 修改后字符串
self.strongtitleSet: 0x282f1ccf0 , 0x1017069e0 , 修改后字符串
self.ccopytitleSet: 0x282f1cab0 , 0x1017069e8 , 初始化可变字符串

通过打印对应的对象地址,指针地址,对象地址存储的值可以得出以下结论:

一,当变量为不可变字符串时,无论通过点语法赋值还是通过下划线赋值,当前属性指向的内存不变,使用strong或copy无区别。
二.当变量为一个可变字符串:分两种情况

1)当通过下划线赋值时,属性指向的内存空间不变,并且当可变字符串内容发生更改时,被赋值的属性也会发生变化。
2)当通过点语法进行赋值时,strong 修饰的属性指向的内存地址并没有发生改变,只是引用计数加一,当可变字符串内容发生更改时,strong修饰的属性值也会发生更改。但是copy 修饰的属性 指向的内存地址会发生更改,并且当我们对可变字符串进行更改时,copy修饰的属性值并不会发生改变,进而说明copy修饰的属性在底层实现时会重新copy一份内存,并指向这块内存,即深拷贝。
3)下划线属性赋值和通过点语法进行属性赋值有很大差距,这就要说起成员变量和属性的差异,属性在低层的实现,是生成一个带下划线的成员变量,同时生成get和set方法。当我们通过下划线对属性赋值时其实是对成员变量进行赋值,而当你对底层有足够多的了解时,其实copy修饰的属性在底层的实现是通过,set_propety 方法访问内存,而非copy修饰的属性,会通过内存偏移的方式访问内存。所以当使用点语法赋值时会自动调用系统的set方法。set方法的底层实现可以参考:iOS底层原理之类,元类数据结构探索

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值