Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to use copied NSMutableString property causes an exception

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 ?

like image 409
rustylepord Avatar asked Aug 16 '12 17:08

rustylepord


1 Answers

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.

like image 87
omz Avatar answered Nov 15 '22 06:11

omz