【问题标题】:How to Implement deep and shallow copy for NSMutableArray in iOS?如何在 iOS 中实现 NSMutableArray 的深浅复制?
【发布时间】:2013-02-24 09:02:05
【问题描述】:

我正在尝试为 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);

这个程序的输出是,

深拷贝:
之前旧阵列的长度:4
之后旧数组的长度:4

浅拷贝:
之前旧阵列的长度:4
之后旧数组的长度:4

我不知道为什么浅拷贝删除没有反映到原始 NSMutableArray。

【问题讨论】:

  • 一开始就初始化 deepCopyshallowCopy 然后重新分配它们既浪费又可能是泄漏,如果您不使用 ARC。

标签: ios shallow-copy deep-copy


【解决方案1】:

你可以这样理解..

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);

输出是:

(-[ViewController viewDidLoad]) (ViewController.m:34) 之前旧数组的长度:4 (-[ViewController viewDidLoad]) (ViewController.m:36) 之后旧数组的长度:4 (-[ViewController viewDidLoad]) (ViewController.m:39) 之前旧数组的长度:4 (-[ViewController viewDidLoad]) (ViewController.m:41) 之后旧数组的长度:3

浅拷贝和深拷贝的概念是:

如果 B 是 A 的浅拷贝,那么它就像 B = [A assign];

B和A指向同一个内存位置

如果 B 是 A 的深拷贝,那么就像 B = [A copy];

B 和 A 指向不同的内存位置

B 内存大小与 A 相同

B与A的内容相同

【讨论】:

    【解决方案2】:

    这是因为initWithArray: 没有进行浅拷贝。您将获得一个全新的数组,其中包含指向与另一个数组相同的对象的指针。

    例如如果您添加的对象是可变字符串,您可以更改其中一个,并且它在新数组和旧数组中都可见,因为它们指向相同的可变字符串。

    另一方面,使用initWithArray:copyItems: 创建的数组不会受到上述更改的影响,因为它指向原始数组中的对象的副本。

    【讨论】:

    • 我能知道我们如何在ios中实现浅拷贝和深拷贝吗?
    • @RoobanAbraham 现在我想起来了,您在问题中看到的行为不是浅拷贝的行为吗?但是,您期望它做的不是浅拷贝的行为。要获得您在问题中谈论的行为,您只需创建另一个指向原始数组的指针。
    【解决方案3】:

    如果 NSArray/NSDictionary 包含 JSON Serialisable 数据,则可以使用 NSJSONSerialization 轻松实现深度复制。

    只需使用NSJSONSerialization 获取NSArray 中的NSData,然后重新创建JSON 对象,这将创建一个全新的NSArray/NSDictionary 的全新副本以及它们的新内存引用。

    但要确保 NSArray/NSDictionary 的对象及其子对象必须是 JSON 可序列化的。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-18
      • 1970-01-01
      • 1970-01-01
      • 2011-09-11
      • 2015-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多