copying NSArray
If we are to use [NSArray copy]. The source array and copy array are pointing to the same address.
If we are to use [NSArray mutableCopy]. The source array and copy array have created their own NSArray, and thus have different addresses.
However, the User pointers inside the copy array points to the same Users pointed to by the source array. This is shown in the image. Thus, after using [NSArray mutableCopy], array and copyArray may have different array objects, but they all point to the same User objects.
Simple pointing
Run the source code and debug it. Analyze the the variables and their addresses.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
User * aUser = [[User alloc] initWithName:@"ricky" andEmail:@"rtsao@usc.edu" andPassword:@"haha" andNewPhotoLocation:@"/usr/var" andNewFlowHistoryTableName:@"ricky_flow_table"]; User * bUser = [[User alloc] initWithName:@"ken" andEmail:@"ken@uci.edu" andPassword:@"hehe" andNewPhotoLocation:@"/usr/var" andNewFlowHistoryTableName:@"ken_flow_table"]; NSLog(@"address of aUser: %p", aUser); NSLog(@"address of bUser: %p", bUser); NSArray * array = [NSArray arrayWithObjects:aUser, bUser, nil]; NSLog(@"address of array: %p", array); NSLog(@"name: %@ email: %@", [[array objectAtIndex:0] name], [[array objectAtIndex:0] email]); NSLog(@"name: %@ email: %@", [[array objectAtIndex:0] name], [[array objectAtIndex:0] email]); NSArray * copyArray = [array copy]; //Just pointing your pointer to the source NSLog(@"address of copyArray: %p", copyArray); NSLog(@"name: %@, email: %@", [[copyArray objectAtIndex:1] name], [[copyArray objectAtIndex:1] email]); NSLog(@"name: %@, email: %@", [[copyArray objectAtIndex:1] name], [[copyArray objectAtIndex:1] email]); aUser.name = @"Rocky"; NSLog(@"name: %@, email: %@", [[copyArray objectAtIndex:0] name], [[copyArray objectAtIndex:0] email]); |
Basically, this is what’s going on:
When we’re doing a shallow copy, changing the name ‘ricky’ to ‘rocky’ will also reflect in the copyArray. Because the source array and copyArray are pointing to the same Users.
Shallow Copy
If you want a shallow copy, change copying to mutable copy
1 |
NSArray * copyArray = [array mutableCopy]; //shallow copy |
In mutable copy, copyArray will have its own array. Look at the bottom portion of the image above. So if you use a NSMutabeArray to receive the return value from mutableCopy, you can add and remove objects. In our image, I used NSArray, and since its immutable, I won’t be able to add or remove array data. Its up to you to decide which one to use.
In other words, you end up with two distinct arrays, so if you were to remove or add items from one array, it wouldn’t affect the other array. However, the items in the two arrays are identical right after the copy.
Therefore, notice that the Users the source array and its mutable copy array pointing to are the same:
In order to do a deep copy, you would have to make a new array, and each element of the new array would be a deep copy of the corresponding element of the old array.
Deep Copy
1 |
NSArray * copyArray = [[NSArray alloc] initWithArray:array copyItems:YES]; //deep copy |
Now, if you were to look at the User’s addresses. They are all different in the 2 distinct arrays. Changing the User at index 0 in array 1, will not affect the User at index 0 in array 2.