我在没有ARC的XCode 6.4下测试copy/retain
属性。
@property(nonatomic, retain) NSMutableString *retainString;
@property(nonatomic, copy) NSMutableString *copyedString;
@synthesize copyedString, retainString;
NSMutableString *mStr = [NSMutableString stringWithFormat:@"abc"];
retainString = mStr;
copyedString = mStr;
NSLog(@"mStr:%p", mStr);
NSLog(@"retainStr:%p", retainString);
NSLog(@"copyStr:%p", copyedString);
[mStr appendString:@"de"];
NSLog(@"retainStr:%@", retainString);
NSLog(@"copyStr:%@", copyedString);
[copyedString appendString:@"123"];
NSLog(@"mStr:%@", mStr);
NSLog(@"copyStr:%@", copyedString);
NSLog(@"retainStr:%@", retainString);
我的问题:
copyedString
应该分配一个新空格,所有三个字符串都具有相同的地址。mString
后,copyedString
不应更改(我知道它们现在已经改变了相同的地址)copyedString
已更改,mStr
和retainString
不应更改。我做错了吗?
以下是日志:
[10656:986440] mStr:0x7f871bd71340
[10656:986440] retainStr:0x7f871bd71340
[10656:986440] copyStr:0x7f871bd71340
[10656:986440] retainStr:abcde
[10656:986440] copyStr:abcde
[10656:986440] mStr:abcde123
[10656:986440] copyStr:abcde123
[10656:986440] retainStr:abcde123
编辑哦,是的,我的错误。 self.property将调用setter和getter,这意味着使用了copy。
所以解决方案是将这两行更改为:
self.retainString = mStr;
self.copyedString = mStr;
但是我遇到了这个崩溃错误:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with appendString:'
*** First throw call stack:
copyedString
成为NSString
吗?
答案 0 :(得分:1)
如果要设置值,则应使用self访问copy属性。
{% url 'auth_login' %}
日志
NSMutableString *mStr = [NSMutableString stringWithFormat:@"abc"];
self.retainString = mStr;
self.copyedString = mStr;
NSLog(@"mStr:%p", mStr);
NSLog(@"retainStr:%p", self.retainString);
NSLog(@"copyStr:%p", self.copyedString);
[mStr appendString:@"de"];
NSLog(@"retainStr:%@", self.retainString);
NSLog(@"copyStr:%@", self.copyedString);
在你的方式,它不复制,它只是使用指针访问地址。所以,它指向相同的地址
修改强>
如果要复制属性返回可变结果,请删除2015-07-24 16:11:19.728 OCTest[13193:268356] mStr:0x7f84034ba020
2015-07-24 16:11:19.729 OCTest[13193:268356] retainStr:0x7f84034ba020
2015-07-24 16:11:19.729 OCTest[13193:268356] copyStr:0x7f84034bfa50
2015-07-24 16:11:19.729 OCTest[13193:268356] retainStr:abcde
2015-07-24 16:11:19.729 OCTest[13193:268356] copyStr:abc
,然后重写
@synthesize
答案 1 :(得分:0)
所有这些变量都是对相同对象的引用:
NSMutableString *mStr = [NSMutableString stringWithFormat:@"abc"];
retainString = mStr;
copyedString = mStr;
因此,通过其他引用可以看到通过一个引用进行的更改。
在几乎所有语言中使用=
运算符并不意味着对象的副本,只是对该对象的引用的副本(异常将是C ++中被覆盖的operator =
,但这很少有人做过)。对于原始类型,这是不同的,其中=
运算符确实意味着副本。
我相信,你想要的是:
copyedString = [mStr mutableCopy];
现在copyedString
是另一个对象。