Search code examples
objective-ccocoacocoa-touchcopynsarray

Does the assignment operator make a shallow copy of an NSArray?


Say I have two arrays:

NSArray *A = @[@"Red", @"Blue", @"Yellow"];
NSArray *B = A;

Is B technically a shallow copy of A? If I make changes to the data contained in A, B sees those same changes, and vice-versa. When looking at copying in Apple's documentation, simple equality via the "=" operator is not mentioned as a valid way to make a shallow copy. If this doesn't constitute a shallow copy, then what is it?


Solution

  • Assignment (in Objective-C) is not a copy at all. That is, it's not a copy of the object, it's only a copy of the reference to the object. There's a reason every object (reference) has to be declared as a pointer. (Blocks are a special case.)

    A shallow copy is done via the copy method, as in: NSArray *B = [A copy];

    As it happens you can't modify NSArrays, but the principle holds for NSMutableArrays as well.

    NSMutableArray *a = [@[@"Red", @"Blue", @"Yellow"] mutableCopy];
    NSMutableArray *b = a;
    NSMutableArray *c = [a mutableCopy];
    
    NSLog(@"%@, %@, %@", a[0], b[0], c[0]);  // Prints: Red, Red, Red
    
    b[0] = @"Green";
    
    NSLog(@"%@, %@, %@", a[0], b[0], c[0]);  // Prints: Green, Green, Red
    
    c[0] = @"Purple";
    
    NSLog(@"%@, %@, %@", a[0], b[0], c[0]);  // Prints: Green, Green, Purple