Reputation: 281
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
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
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
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