In the Foundation framework for iOS and Mac the main container classes (NSString, NSArray, NSDictionary, and some others) have two states; Immutable and Mutable. If a class is immutable, it cannot be changed and is treated as read only. When a class if mutable it can be modified after creation. It may seem that when passing one of these around it may be faster to retain it rather than copy it, because new memory does not need to be allocated. While this is true it can leave instabilities, see this example.
@interface SomeClass : NSObject @property (nonatomic, retain) NSString* text; @end ... SomeClass* test = [[SomeClass alloc] init]; NSMutableString* string = [[NSMutableString alloc] initWithString:@"cat"]; [test setText:string]; [string appendString:@"dog"];
SomeClass sets it’s text property via retaining it. When it gets set, string represents “cat”, but after being set it becomes “catdog”. SomeClass does not expect this and because of it there could be bugs or crashes when using it’s text property. The correct way to handle this is to change the text property from retain to copy. But what’s this you say, doesn’t that mean we create a new copy every time text is set? The Foundation class is a lot smarter than this. If an object you copy is immutable, the object is retained and returned. If an object you copy is mutable, it is always copied into an immutable result. If you make a mutableCopy of an object, it is always copied into a mutable object:
NSString* immutableString = [NSString stringWithString:@"cat"]; NSMutableString* mutableString = [NSMutableString stringWithString:@"cat"];
immutableString: 0x1000028d8 mutableString: 0x101905b60 [immutableString copy]: 0x1000028d8 [mutableString copy]: 0x1005272d0 [immutableString mutableCopy]: 0x101905bc0 [mutableString mutableCopy]: 0x101905c00