views:

9499

answers:

2

Hi All,

Is there any built-in function in Objective-C allows me to deep copy a NSMutableArray?

I looked around, some people say [aMutableArray copyWithZone:nil] works as deep copy. But I tried it seems no.

Right now I am manually doing the copy one by one (a 9*9 array):

//deep copy a 9*9 mutable array to a passed-in reference array

-deepMuCopy : (NSMutableArray*) array 
    toNewArray : (NSMutableArray*) arrayNew {

    [arrayNew removeAllObjects];//ensure it's clean

    for (int y = 0; y<9; y++) {
     [arrayNew addObject:[NSMutableArray new]];
     for (int x = 0; x<9; x++) {
      [[arrayNew objectAtIndex:y] addObject:[NSMutableArray new]];

      NSMutableArray *aDomain = [[array objectAtIndex:y] objectAtIndex:x];
      for (int i = 0; i<[aDomain count]; i++) {

       //copy object by object
       NSNumber* n = [NSNumber numberWithInt:[[aDomain objectAtIndex:i] intValue]];
       [[[arrayNew objectAtIndex:y] objectAtIndex:x] addObject:n];
      }
     }
    }
}

Thank you.

+2  A: 

It's a little bit of a hack, but the only way I know to easily do this is to archive and then immediately unarchive your array.

The catch is that your object must support the NSCoding interface, since this will be used to store/load the data.

NSArray* arrayCopy = [NSUnarchiver unarchiveObjectWithData: [NSArchiver archivedDataWithRootObject: oldArray]];
Andrew Grant
Using NSArchiver and NSUnarchiver is a very heavy solution performance-wise, if your arrays are large. Writing a generic NSArray category method which uses NSCopying protocol will do the trick, causing a simple 'retain' of immutable objects and a real 'copy' of mutable ones.
Nikita Zhuk
+30  A: 

Doesn't it work if you simply use the initWithArray:copyItems: on NSMutableArray.


NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:oldArray copyItems:YES];

That's what they recommend here and what I remember I'm doing in my projects generally: http://lists.apple.com/archives/cocoa-dev/2008/May/msg00172.html

François P.
Seems to be the correct answer. The API states each element gets an [element copyWithZone:] message, which may be what you were seeing. If you are in fact seeing that sending [NSMutableArray copyWithZone:nil] doesn't deep copy, then an array of arrays may not copy correctly using this method.
Ed Marty