NSString属性为什么要用copy修饰

Property-NSString-Copy

NSString 属性为什么应该使用copy修饰,使用strong为什么不行?在之前一直都知道NSString/Blocks类型的属性应该使用copy来修饰,一直没研究过到底为什么?前几天看到一篇blog感觉讲得较完善,那么我也把自己的一点体会和理解记录下吧,欢迎指正。

  • 我们先定义一个测试类BMPerson
@interface BMPerson : NSObject
@property (strong, nonatomic) NSString *strStrong; ///< strStrong
@property (copy, nonatomic) NSString *strCopy; ///< strCopy
@property (strong, nonatomic) NSObject *obj; ///< obj
@end

@implementation BMPerson
- (void)logFunc {
    NSLog(@"_strStrong的内容: %@  _strStrong 存放的地址:%p _strStrong 的地址:%p", _strStrong, _strStrong, &_strStrong);
    NSLog(@"_strCopy的内容: %@  _strCopy 存放的地址:%p _strCopy 的地址:%p", _strCopy, _strCopy, &_strCopy);
}
@end
  • main函数中执行如下代码:
NSString *str = @"abc";
BMPerson *per = [BMPerson new];
per.strStrong = str;
per.strCopy = str;
NSLog(@"str修改前: str的内容: %@  str 存放的地址:%p str 的地址:%p", str, str, &str);
[per logFunc];
NSLog(@"\n");
str = @"qwe";
NSLog(@"str修改后: str的内容: %@  str 存放的地址:%p str 的地址:%p", str, str, &str);
[per logFunc];

会输出如下的log

035304+0800 Demo[58039:7367327] str修改前: str的内容: abc  str 存放的地址:0x100002098 str 的地址:0x7fff5fbff748
035455+0800 Demo[58039:7367327] _strStrong的内容: abc  _strStrong 存放的地址:0x100002098 _strStrong 的地址:0x100200198
035483+0800 Demo[58039:7367327] _strCopy的内容: abc  _strCopy 存放的地址:0x100002098 _strCopy 的地址:0x1002001a0
035503+0800 Demo[58039:7367327] 
035513+0800 Demo[58039:7367327] str修改后: str的内容: qwe  str 存放的地址:0x1000020f8 str 的地址:0x7fff5fbff748
035522+0800 Demo[58039:7367327] _strStrong的内容: abc  _strStrong 存放的地址:0x100002098 _strStrong 的地址:0x100200198
035543+0800 Demo[58039:7367327] _strCopy的内容: abc  _strCopy 存放的地址:0x100002098 _strCopy 的地址:0x1002001a0
  • 似乎是strongcopy没有任何区别,那么我们换一种方式看看。
NSMutableString *str = [NSMutableString stringWithFormat:@"abc"];
BMPerson *per = [BMPerson new];
per.strStrong = str;
per.strCopy = str;
NSLog(@"str修改前: str的内容: %@  str 存放的地址:%p str 的地址:%p", str, str, &str);
[per logFunc];
NSLog(@"\n");
[str appendString:@"+a"];
NSLog(@"str修改后: str的内容: %@  str 存放的地址:%p str 的地址:%p", str, str, &str);
[per logFunc];

会输出如下的log

035625+0800 Demo[58039:7367327] str修改前: str的内容: abc  str 存放的地址:0x100200a80 str 的地址:0x7fff5fbff738
035735+0800 Demo[58039:7367327] _strStrong的内容: abc  _strStrong 存放的地址:0x100200a80 _strStrong 的地址:0x100200198
035755+0800 Demo[58039:7367327] _strCopy的内容: abc  _strCopy 存放的地址:0x63626135 _strCopy 的地址:0x1002001a0
035760+0800 Demo[58039:7367327] 
035770+0800 Demo[58039:7367327] str修改后: str的内容: abc+a  str 存放的地址:0x100200a80 str 的地址:0x7fff5fbff738
035778+0800 Demo[58039:7367327] _strStrong的内容: abc+a  _strStrong 存放的地址:0x100200a80 _strStrong 的地址:0x100200198
035794+0800 Demo[58039:7367327] _strCopy的内容: abc  _strCopy 存放的地址:0x63626135 _strCopy 的地址:0x1002001a0

我们发现本来给 per.strStrong 赋值的是 @“abc”,但在修改了str后发现per.strStrong的值也变了,但是使用copy修饰的并不会变化,那么到底是什么问题呢?我在blog的基础上简单画了下内存分配图如下:

  • 第一种方式


  • 第二种方式


  • 由上面的图我相信可以清楚发现问题的所在了,使用我们声明NSSring声明的属性时尽量使用copy吧。

Demo地址

Demo地址 https://github.com/asiosldh/Property-NSString-Copy

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 现在中国家庭孩子们做家务越来越少,因为大部分都是独生子女,家里有老人帮照顾,所以,孩子从小就过惯了衣来张手,饭来张...
    与鑫同行阅读 4,768评论 0 3
  • 话说一日午后,徐文长行吟至村郊,忽遇一不盈尺宽的石条桥(浙江山阴乡间多溪流小桥),跨距倒有一丈开外。文长正欲举足,...
    青崖白鹿A阅读 3,060评论 2 0
  • 来斯里兰卡一个月啦,最近真的是好忙,其实一直没有静下心来做一个梳理,一直敷在项目表面。最近静下心来做一个梳理,也算...
    小冰雁的珅哥哥阅读 1,131评论 0 1