Ios NSMutableString retain/copy是相同的(复制不起作用?)
我正在测试XCode 6.4下的Ios NSMutableString retain/copy是相同的(复制不起作用?),ios,objective-c,Ios,Objective C,我正在测试XCode 6.4下的copy/retain属性,没有ARC @property(nonatomic, retain) NSMutableString *retainString; @property(nonatomic, copy) NSMutableString *copyedString; @synthesize copyedString, retainString; NSMutableString *mStr = [NSMutableString stringWi
copy/retain
属性,没有ARC
@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
和保留
不应更改[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
编辑是的,我错了。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
?所有这些变量都是对同一对象的引用:
因此,通过一个引用所做的更改可以通过其他引用看到
使用<代码> =/COD>运算符,在几乎任何语言中,并不意味着对象的拷贝,只是该对象引用的副本(异常将是C++中的重写<代码>运算符=< /COD>,但这很少有人做过)。对于基元类型,这是不同的,
=
操作符确实意味着一个副本
我相信你想要的是:
copyedString = [mStr mutableCopy];
现在,
copyedString
是另一个对象。如果要设置值,应该使用self来访问copy属性
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);
日志
按照您的方式,它不是复制,它只是使用指针访问地址。所以,它指向相同的地址
编辑
如果要复制属性返回可变结果,请删除@synthesis
,然后重写
-(void)setCopyedString:(NSMutableString *)copyedString{
_copyedString = [copyedString mutableCopy];
}
当mString被分配给copyedString时,它不会为copyedString分配新空间吗?如果我使用[mStr mutableCopy];为什么我需要“复制”属性?没错;正如我在回答中提到的,对对象使用
=
只会复制对对象的引用,而不是对象本身。使用copy
和mutableCopy
方法克隆对象是必要的。'='复制引用并将'retain'属性的retainCount增加1,但对于'copy'则不是,对吗?我想测试这个,但是您使用“mutableCopy”在什么测试上没有帮助。您这样认为吗?copiedString
和retainedString
是实例变量。它们仅仅是赋值并不会导致复制,而是保留。它崩溃了,因为-[NSMutableString copy]
returnNSString
是不可变的。
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
-(void)setCopyedString:(NSMutableString *)copyedString{
_copyedString = [copyedString mutableCopy];
}