浅拷贝和深拷贝之间的区别

时间:2014-04-10 06:04:17

标签: objective-c

我一直在尝试通过以下链接了解深层和浅层副本之间的区别:Difference

我做了什么:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    tempArray=[[NSMutableArray alloc] initWithObjects:@"A",@"B",@"C",@"D",@"E",@"F",@"G", nil];
    shallowArray=[[NSMutableArray alloc] initWithArray:tempArray copyItems:NO];
    deepArray=[[NSMutableArray alloc] initWithArray:tempArray copyItems:YES];
}

- (IBAction)testShallowDeep:(id)sender {

    [tempArray removeObjectAtIndex:0];
    NSLog(@"ShallowArray should get changed==%@",shallowArray);
    NSLog(@"DeepArray should remain Same===%@'",deepArray);
}

然而,当我检查日志时,两者都与临时数组相同。任何人都可以用上面的例子解释这个概念。根据我的理解,浅阵应该改变和 元素'A'应该从中移除,Deep Array应该与temp Array保持一致。

2 个答案:

答案 0 :(得分:6)

所以你在这里基本上做的是创建三个数组,其中tempArrayshallowArray指向相同的对象,deepArray指向副本。

在实例化数组后,最初它是这样的:
enter image description here

tempArrayshallowArray都指向相同的对象。但阵列本身就是不同的对象!

之后

[tempArray removeObjectAtIndex:0]

这是情况: enter image description here

您似乎怀疑的行为可以通过让shallowArray指向与tempArray相同的对象来实现:

shallowArray = tempArray;

答案 1 :(得分:0)

你是对的,你在这里使用的代码应该与你上面说的相同。但是我发现可能导致问题的是这个方法返回一个新分配的数组,并且Array中的每个对象都会收到一条copyWithZone:消息。声明的第一部分强烈讨论你的问题,因为每个阵列都有它自己的记忆,同时苹果医生说这里应该有一个浅的副本(你上面给出的链接)。我担心你在这里和ARC copyWithZone使用ARC:不可用。这可能会阻止数组在这里有浅拷贝。这意味着新阵列没有获得旧阵列的区域。如果这些情况都不是;然后有人必须向Apple提交报告以澄清这类事情。

编辑:

你的问题的答案就在这里。一切都很好,在这里可以。是这里的浅色副本。但是我在这里注意到的一件事深拷贝也指向了浅存储位置和临时存储位置相同的存储位置。在你的场景中。 temparry的第一个对象有内存位置说0x13df19。对于浅拷贝也是如此。对于深度阵列来说,它必须是不同的,但坐在我身边的却是相同的。好了,问题,当你从临时数组中删除对象。对象地址被删除。根据文档,浅和临时数组的对象指向相同的位置。并不是整个阵列都是一样的。因此,当您从临时数组中删除对象时,它将被删除,但该对象将在内存中,并将驻留在已添加的每个数组中。你正在谈论的场景看起来像这样

someArray = tempArray;
[tempArray removeObjectAtIndex:0];
NSLog(@"Updated Array should get changed==%@",someArray);

现在这将与temp数组具有相同的数组,因为它们指向相同的内存位置。