Does mutableCopy modify contained objects?

myArray is an NSArray of NSDictionary objects. Will [myArray mutableCopy] contain original NSDictionary objects or copies of NSMutableDictionary? Is there an easy way to make an immutable graph of objects completely mutable?

+2
objective-c cocoa nsmutablearray
Dec 28 '11 at 9:59 p.m.
source share
3 answers

If you don't mind the amount of time it takes for a large graph of objects, and really want to get deep copies of the objects, you can serialize the graph of objects and then deserialize it. The easiest way to do this (assuming all your objects are Foundation Collection objects) is to use the NSPropertyListSerialization class. Serialize your root object to data, then deserialize to your mutable root level array using the NSPropertyListMutableContainersAndLeaves parameter. Your resulting volatile array at the root level will be a deep copy, and all containers will be volatile. It is important to remember that this will indeed be a deep copy, so if you change something in another container, this change will not be reflected in the original objects.

Here is a quick code example:

 // Assumes the root-level object is an array, adjust as necessary - (NSMutableArray*)deepMutableCopyOfArray:(NSArray*)array error:(NSError**)outError { NSError* error = nil; NSData* serializedData = [NSPropertyListSerialization dataWithPropertyList:array format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error]; if( !serializedData ) { if( outError ) *outError = error; return nil; } NSMutableArray* mutableCopy = [[NSPropertyListSerialization propertyListWithData:serializedData options:NSPropertyListMutableContainersAndLeaves format:NULL error:&error] retain]; if( !mutableCopy ) { if( outError ) *outError = error; return nil; } return mutableCopy; } 
+7
Dec 28 2018-11-12T00:
source share

Copies in Cocoa are usually small. This means that this only affects the topmost object, in this case the array. You will get a volatile array of immutable dictionaries. There is not a single liner to make the whole thing changeable, as you ask.

+2
Dec 28 '11 at 22:02
source share

The only way to do this is to iterate over the original array, create mutable copies of each object, and replace the immutable objects in the mutable array with their mutable siblings. Wal, the word mutable has lost all meaning.

 NSArray *mutableArray = [originalArray mutableCopy]; for (NSDictionary *dictionary in originalArray) { NSInteger index = [originalArray indexOfObject:dictionary]; NSMutableDictionary *mutableDictionary = [dictionary mutableCopy]; [mutableArray replaceObjectAtIndex:index withObject:mutableDictionary]; } 

It should be clear that you can work even further in a graph with nested loops. Depending on the size of the array, you may need a backup pool for storing memory.

+1
Dec 28 2018-11-12T00:
source share



All Articles