我需要NSArray
的副本来存储日期状态。我尝试使用我理解的mytableCopy
制作独立于原始对象的副本。
当我对mutableCopy
进行更改时,我在原始数组中也有更改。
为什么?
我的代码是:
_nsarr = [[NSArray alloc] initWithArray:inputArray];
_nsMraa= [NSMutableArray alloc];
_nsMraa = [_nsarr mutableCopy];
注意:两个数组都是我的对象的属性。 inputArray
是输入参数,之后不再使用。
备注:一个对象为NSArray
,另一个为NSMutableArray
答案 0 :(得分:2)
正如Bharat和Milan所提到的,NSArray
是一个引用类型数组,它包含一个指针数组。调用mutableCopy
将生成数组的浅表副本并使副本可变,原始仍然是不可变的。但是mutableCopy
和copy
都不会对数组的CONTENTS执行深层复制。 ARRAY是否变得可变,而不是数组中保存的对象的内容。
假设如下:
@interface MyObject
- (int) state;
- (void) setState:(int) state;
@end
...
_nsarr = [NSArray arrayWithObject:[[MyObject alloc] initWithState]];
_nsmarr = [_nsarr mutableCopy];
此时你有两个不同的数组,_nsarr
和_nsmarr
,一个不可变,一个是,_nsarr[0]
和_nsmarr[0]
仍然是同一个对象,这意味着[_nsarr[0] setState:1]
有效,并且它与[_nsmarr[0] setState:1]
具有完全相同的效果
[_nsarr[0] setState:1];
NSLog("%d", [_nsmarr[0] state]); // ==> 1
[_nsarr[0] setState:2];
NSLog("%d", [_nsmarr[0] state]); // ==> 2
要复制数组中包含的各个对象,需要创建数组的“深层”副本,这意味着要复制数组的内容(递归)以及数组本身。没有快速简便的方法来创建数组的深层副本,因为它很大程度上取决于如何(如果?)您可以对引用的对象进行深层复制。 Bharat提出了一种方法(由于它对对象进行序列化和反序列化,并且要求它们遵守NSCoding
),因此成本很高:一种方法可能类似于:
_nsmarr = [NSArray withCapacity:[_nsarr count]];
for(MyObject* foo in _nsarr) {
[_nsmarr addObject:[foo copy]];
}
假设foo实现了NSCopying
协议,这基本上与米兰建议的initWithArray:copyItems:方法相同:
_nsmarr = [[NSMutableArray alloc] initWithArray:_nsarr copyItems:YES];
答案 1 :(得分:1)
试试这个
_nsMraa = [[NSArray alloc]initWithArray:_nsarr copyItems:YES];
答案 2 :(得分:0)
如果您需要真正的深层拷贝,例如当您拥有阵列数组时,只要内容全部符合NSCoding协议,您就可以归档然后取消归档该集合。这种技术的一个例子如下所示。
真正的深层复制
NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
[NSKeyedArchiver archivedDataWithRootObject:oldArray]];