复制对象

来源:互联网 发布:mac word2016 取代功能 编辑:程序博客网 时间:2024/06/07 08:43

一.copy和mutableCopy方法
Foundation类实现了为copy和mutableCopy的方法, 可以使用这些方法创建对象的副本。通过实现一个符合协议(用于制作副本)的方法来完成此任务。如果类必须区分要产生对象的是可变副本还是不可变副本,还需要根据协议实现的一个方法。
语句:
dataArray2 = [dataArray mutableCopy];
在内存中创建了一个新的dataArray副本,并复制了它的所有元素。随后,执行语句:
[dataArray2 removeObjectAtIndex : 0];
删除了dataArray2的第一个元素,但却不删除dataArray的第一个元素
创建一个dataArray的可变副本并将它赋值给dataArray2的最终副本。这就在内存中创建了两个截然不同的可变数组。现在,删除dataArray2的第一个元素时,不会对dataArray的内容有任何影响,
注意,产生一个对象的可变副本并不要求被复制的对象本身是可变的。这种情况同样适用与不可变副本:可以创建可变对象的不可变副本
二.浅复制与深复制
使用下面的语句检索dataArray的第一个元素
mStr = dataArray[0];
然后,使用下面的语句将字符串@”ONE”附加到这个元素中:
[aStr appendString:@”ONE”];
注意原始数组以及其副本中第一个元素的值都被修改了。 从集合中获取元素时,就得到了这个元素的一个新引用,但并不是一个新副本。所以,dataArray[0]返回的对象与dataArray中第一个元素都指向内存中的同一对象,随后,修改字符串对象mStr的副作用就是同时改变了dataArray的第一个元素。
为什么副本的第一个元素也会变呢,这与默认的浅复制方式有关。它意味着使用mutableCopy方法复制数组时,在内存中为新的数组对象分配了空间,并且将单个元素复制到新数组中,然而原始数组中的每个元素复制到新位置意味着: 仅将引用从一个数组元素复制到另一个数组元素。这样做的最终结果,就是这两个数组中的元素都指向内存中同一个字符串。这与将一个对象复制给另一个对象没有区别。
若要为数组中的每个元素都创建完全不同的副本,需要执行所谓的深复制。 这就意味着要创建数组中每个对象的副本,而不仅是这些对象引用的副本。然而使用Foundation类的copy或者mutableCopy方法时,深复制并不是默认执行的。所以需要我们手动创建。
比如,需要更改dataArray2中的第一个元素,但不更改dataArray中的第一个元素,可以创建一个新的字符串,并将它存储到dataArray2的第一个位置:
mStr = [NSMutableString stringWithString: dataArray2[0]];
然后,可以更改mStr,并使用replaceObjectatIndex:withObject方法将它添加到数组中:
[mStr appendString@”ONE”];
[dataArray2 replaceObjectAtIndex: 0 withObject : mStr];
唐隽

0 0