Reputation: 16149
I am testing copy/retain
property under XCode 6.4 without 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);
My questons:
copyedString
should alloc a new space, the all the three strings has the same address.mString
was changed, copyedString
shouldn't be changed(I know they are the same address now so changed)copyedString
changed, mStr
and retainString
shouldn't be changed.Am i make something wrong?
Here are the logs:
[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
EDIT oh yes, my mistake. self.property will call the setter and getter which means copy was used.
So the solution is change these two lines to:
self.retainString = mStr;
self.copyedString = mStr;
But i got this crash error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with appendString:'
*** First throw call stack:
Does copyedString
become NSString
?
Upvotes: 2
Views: 86
Reputation: 24714
You should use self to access copy property if you want to set value.
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);
Log
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
In your way,it not copy,it just use pointer to access the address.So,it point to same address
Edit
If you want copy property return mutable result,delete the @synthesize
,and rewrite
-(void)setCopyedString:(NSMutableString *)copyedString{
_copyedString = [copyedString mutableCopy];
}
Upvotes: 1
Reputation: 122391
All of those variables are references to the same object:
NSMutableString *mStr = [NSMutableString stringWithFormat:@"abc"];
retainString = mStr;
copyedString = mStr;
So changes made via one reference are visible via the other references.
Using the =
operator, in pretty much any language, does not imply a copy of the object, just a copy of the reference to that object (exception would be an overridden operator =
in C++, but that's rarely ever done). This is different for primitive types, where the =
operator does imply a copy.
What you want, I believe, is:
copyedString = [mStr mutableCopy];
and now copyedString
is a different object.
Upvotes: 0