Rooban Ponraj A
Rooban Ponraj A

Reputation: 281

How to Implement deep and shallow copy for NSMutableArray in iOS?

I am trying to implement deep and shallow copy for NSMutableArray,

self.oldArray =[[NSMutableArray alloc] initWithCapacity:0];
self.shallowCopy =[[NSMutableArray alloc] initWithCapacity:0];
self.deepCopy =[[NSMutableArray alloc] initWithCapacity:0];


//add object to old Array
[self.oldArray addObject:@"rooban"];
[self.oldArray addObject:@"radha"];
[self.oldArray addObject:@"jesus"];
[self.oldArray addObject:@"god"];


self.shallowCopy=[[NSMutableArray alloc] initWithArray:self.oldArray];
self.deepCopy=[[NSMutableArray alloc] initWithArray:self.oldArray copyItems:YES];

//deep copy
NSLog(@"Lenght of the Old Array before: %d",self.deepCopy.count);
[self.deepCopy removeObject:@"rooban"];
NSLog(@"Lenght of the Old Array After: %d",self.oldArray.count);

//shallow copy
NSLog(@"Lenght of the Old Array Before: %d",self.shallowCopy.count);
[self.shallowCopy removeObject:@"rooban"];
NSLog(@"Lenght of the Old Array After: %d",self.oldArray.count);

the output of this program is,

deep copy :
Lenght of the Old Array before: 4
Lenght of the Old Array After: 4

shallow copy :
Lenght of the Old Array Before: 4
Lenght of the Old Array After: 4

I don't know why shallow copy deletion not reflecting to original NSMutableArray.

Upvotes: 0

Views: 1677

Answers (3)

Mrug
Mrug

Reputation: 5023

If NSArray/NSDictionary contains JSON Serialisable data then Deep copy can be easily achieved using NSJSONSerialization.

Simply take NSData of NSArray using NSJSONSerialization and then recreate JSON Object, this will create a complete new and fresh copy of NSArray/NSDictionary with new memory references of them.

But make sure the objects of NSArray/NSDictionary and their children must be JSON serializable.

NSData *aDataOfSource = [NSJSONSerialization dataWithJSONObject:oldCopy options:NSJSONWritingPrettyPrinted error:nil];
NSDictionary *aDictNewCopy = [NSJSONSerialization JSONObjectWithData:aDataOfSource options:NSJSONReadingMutableLeaves error:nil];

Upvotes: 0

David Rönnqvist
David Rönnqvist

Reputation: 56625

This happens because initWithArray: is not doing a shallow copy. You are getting a completely new array with pointers to the same objects as the other array.

E.g. if the objects you added were mutable strings you could change one of them and it would be visible in both the new and old array since they point to the same mutable string.

On the other hand, the array created with initWithArray:copyItems: would not be affected by the above change since it points to copies of the objets that were in the original array.

Upvotes: 1

iOS_User
iOS_User

Reputation: 1382

You can understand like this..

NSMutableArray *oldArray =[[NSMutableArray alloc] initWithCapacity:0]; NSMutableArray *shallowCopy; // =[NSMutableArray arrayWithCapacity:0]; NSMutableArray *deepCopy; // =[[NSMutableArray alloc] initWithCapacity:0];

//add object to old Array
[oldArray addObject:@"rooban"];
[oldArray addObject:@"radha"];
[oldArray addObject:@"jesus"];
[oldArray addObject:@"god"];


shallowCopy = oldArray;
deepCopy = [oldArray mutableCopy];

//deep copy
NSLog(@"Lenght of the Old Array before: %d",deepCopy.count);
[deepCopy removeObject:@"rooban"];
NSLog(@"Lenght of the Old Array After: %d",oldArray.count);

//shallow copy
NSLog(@"Lenght of the Old Array Before: %d",shallowCopy.count);
[shallowCopy removeObject:@"rooban"];
NSLog(@"Lenght of the Old Array After: %d",oldArray.count);

Output is:

(-[ViewController viewDidLoad]) (ViewController.m:34) Lenght of the Old Array before: 4 (-[ViewController viewDidLoad]) (ViewController.m:36) Lenght of the Old Array After: 4 (-[ViewController viewDidLoad]) (ViewController.m:39) Lenght of the Old Array Before: 4 (-[ViewController viewDidLoad]) (ViewController.m:41) Lenght of the Old Array After: 3

the concept is for Shallow copy and Deep copy is:

If B is a shallow copy of A, then it is like B = [A assign];

B and A point to the same memory location

If B is a deep copy of A, then it is like B = [A copy];

B and A point to different memory locations

B memory size is same as A's

B has same contents as A's

Upvotes: 2

Related Questions