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
- 似乎是
strong
和copy
没有任何区别,那么我们换一种方式看看。
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