NSMutableString保留/复制是否相同(复制不起作用?)

时间:2015-07-24 07:51:31

标签: ios objective-c

我在没有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);

我的问题:

  1. copyedString应该分配一个新空格,所有三个字符串都具有相同的地址。
  2. 更改mString后,copyedString不应更改(我知道它们现在已经改变了相同的地址)
  3. copyedString已更改,mStrretainString不应更改。
  4. 我做错了吗?

    以下是日志:

    [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吗?

2 个答案:

答案 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是另一个对象。