I started a small Xcode project to investigate whether an NSMutableString
property should be copy
or retain
. I declared my property with the copy
attribute:
@property (nonatomic,copy) NSMutableString *stringA;
Then initialized it as self.stringA = [NSMutableString new];
finally tried to set a string [stringA setString:@"A"];
.
However the program gives,
"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with setString:'"
Is it because the resulting string is a NSString
? Does this mean I should declare my NSMutableString
properties using retain
attribute and NSString
properties using copy
?
You're right, the copy
method of NSMutableString
returns an immutable NSString
. This is a convention in Cocoa, it also applies to NSMutableArray
, NSMutableDictionary
, etc.
So if you want your property to remain mutable, you should declare it as retain
. If you need copy semantics, but still want the result to be mutable, you'd have to implement your own setter for the property (and use mutableCopy
to do the copying).
The reason you commonly see copy
for string properties is that it's often desirable to have a guarantee that a string is immutable, regardless of what kind of string is assigned to the property. Otherwise you might end up accidentally modifying the same string elsewhere, which can be difficult to debug. Immutable objects also have the benefit of being thread-safe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With