以下是测试代码:
@property (nonatomic,strong)NSString *strStro;
@property (nonatomic,copy)NSString *strCop;
@property (nonatomic,strong)NSMutableString *strMutab;
@property (nonatomic,retain)NSString *strReta;
@property (nonatomic,assign)NSString *strAssi;
@property (nonatomic,weak)NSString *strWeak;
self.strMutab = [NSMutableStringstringWithFormat:@"a mutable string"];
NSLog(@"%@ %p",_strMutab,_strMutab);
self.strStro =self.strMutab;
self.strCop =self.strMutab;
self.strReta =self.strMutab;
self.strAssi =self.strMutab;
self.strWeak =self.strMutab;
NSLog(@"%@ %p",_strMutab,_strMutab);
NSLog(@"%@ %p",_strCop,_strCop);
NSLog(@"%@ %p",_strStro,_strStro);
NSLog(@"%@ %p",_strReta,_strReta);
NSLog(@"%@ %p",_strAssi,_strAssi);
NSLog(@"%@ %p",_strWeak,_strWeak);
[self.strMutabappendString:@"append string"];
NSLog(@"%@ %p",_strMutab,_strMutab);
NSLog(@"%@ %p",_strCop,_strCop);
NSLog(@"%@ %p",_strStro,_strStro);
NSLog(@"%@ %p",_strReta,_strReta);
NSLog(@"%@ %p",_strAssi,_strAssi);
NSLog(@"%@ %p",_strWeak,_strWeak);
以下是打印结果(arc下):
2015-03-19 22:13:52.245 MyTestProject[1270:386094] a mutable string 0x7fc2eb553cf0
2015-03-19 22:13:58.995 MyTestProject[1270:386094] a mutable string 0x7fc2eb553cf0
2015-03-19 22:14:04.149 MyTestProject[1270:386094] a mutable string 0x7fc2eb67ff80
2015-03-19 22:14:08.522 MyTestProject[1270:386094] a mutable string 0x7fc2eb553cf0
2015-03-19 22:14:12.247 MyTestProject[1270:386094] a mutable string 0x7fc2eb553cf0
2015-03-19 22:14:22.289 MyTestProject[1270:386094] a mutable string 0x7fc2eb553cf0
2015-03-19 22:14:52.441 MyTestProject[1270:386094] a mutable string 0x7fc2eb553cf0
2015-03-19 22:14:58.420 MyTestProject[1270:386094] a mutable stringappend string 0x7fc2eb553cf0
2015-03-19 22:15:07.082 MyTestProject[1270:386094] a mutable string 0x7fc2eb67ff80
2015-03-19 22:15:11.454 MyTestProject[1270:386094] a mutable stringappend string 0x7fc2eb553cf0
2015-03-19 22:15:14.332 MyTestProject[1270:386094] a mutable stringappend string 0x7fc2eb553cf0
2015-03-19 22:15:16.227 MyTestProject[1270:386094] a mutable stringappend string 0x7fc2eb553cf0
2015-03-19 22:15:17.863 MyTestProject[1270:386094] a mutable stringappend string 0x7fc2eb553cf0
结论:NSString属性最好用copy修饰,因为nsmutablestring属性可以赋值给nsstring属性(nsstring是nsmutablestring的父类),如果此后nsmutablestring属性发生了变化,只有用copy才能保证nsstring属性不变。否则nsstring属性会跟着变化,因为指向的是同一块内存地址。
但是对于nsarray即使用的是copy,也不会copy内存,貌似和strong的效果相同。(更新:此句我后来又验证了一下,应该还是有区别的,和string一样,nsarray也会copy一个新的内存,上面红字的错误结论是因为没有用存取器访问属性的setter方法)。
属性代码:
@property (nonatomic, copy) NSArray *myArray;
验证代码:
NSMutableArray *arr = [[NSMutableArray alloc]init];
[arr addObject:@"one"];
[arr addObject:@"two"];
self.myArray = arr;
NSLog(@"%@ %p %@ %p", arr, arr, self.myArray, self.myArray);
[arr addObject:@"three"];
NSLog(@"%@ %p %@ %p", arr, arr, self.myArray, self.myArray);
打印结果:
2015-05-09 18:07:33.761 Test_5_2[1563:232284] (
one,
two
) 0x7fecf0e33320 (
one,
two
) 0x7fecf0d23c10
2015-05-09 18:07:35.086 Test_5_2[1563:232284] (
one,
two,
three
) 0x7fecf0e33320 (
one,
two
) 0x7fecf0d23c10
可见myArray属性在指向一个nsmutablearray属性的时候确实copy了一块新的内存,原mutablearray的改变(元素增减),不会对myArray造成影响。只不过我们平时一般用nsmutablearray,但如果需要避免这种情况,还是一定要用copy修饰。
而我之前的错误结论的验证代码如下:
属性一样,用copy修饰:
@property (nonatomic, copy) NSArray *myArray;
验证:
NSMutableArray *arr = [[NSMutableArray alloc]init];
[arr addObject:@"one"];
[arr addObject:@"two"];
_myArray = arr;
NSLog(@"%@ %p %@ %p", arr, arr, _myArray, _myArray);
[arr addObject:@"three"];
NSLog(@"%@ %p %@ %p", arr, arr, _myArray, _myArray);
注意这次我用_myArray来访问属性,也就是没有调用myArray属性的setter方法,我们看看打印结果。
2015-05-09 18:18:26.817 Test_5_2[1632:273367] (
one,
two
) 0x7fd118d8b510 (
one,
two
) 0x7fd118d8b510
2015-05-09 18:18:47.219 Test_5_2[1632:273367] (
one,
two,
three
) 0x7fd118d8b510 (
one,
two,
three
) 0x7fd118d8b510
内存地址一样,没有copy新地址。所以看起来copy无效。所以要想copy有效,除了copy修饰属性以外,还要记得用点语法访问属性,以调用setter方法,即self.myArray。
注意:一定要用self.strCop来调用属性,这样保证调用了系统的setter方法,而涉及到内存空间拷贝的代码,应该就写在了setter方法里,所以如果这样_strCop调用,不会拷贝新地址。