简体   繁体   English

如何创建NSArray副本并在不影响原始NSArray的情况下进行更改?

[英]How to create copy of NSArray and change it without affection original NSArray?

I need a copy of NSArray to store state of dates. 我需要一个NSArray副本来存储日期状态。 I try to use mytableCopy which I understand makes copy which is independent of original object. 我尝试使用mytableCopy ,据我了解,它使副本独立于原始对象。

When I make changes to mutableCopy I have changes also in the original array. 当我对mutableCopy进行更改时,我在原始数组中也进行了更改。

Why? 为什么?

My code is: 我的代码是:

_nsarr = [[NSArray alloc] initWithArray:inputArray];
_nsMraa= [NSMutableArray alloc];
_nsMraa = [_nsarr mutableCopy];

Note: both arrays are properties of my object. 注意:这两个数组都是我对象的属性。 inputArray is input param which is not use after that. inputArray是输入参数,此后不使用。

REMARK: one object is NSArray , other is NSMutableArray 备注:一个对象是NSArray ,另一个是NSMutableArray

As alluded to by Bharat and Milan, NSArray is an array of reference types, it contains an array of pointers. 正如巴拉特(Bharat)和米兰(Milan)所说, NSArray是引用类型的数组,它包含一个指针数组。 Calling mutableCopy will make a shallow copy of the array and make the copy mutable, the original will still be nonmutable. 调用mutableCopy将创建该数组的浅表副本并使该副本可变,原始副本仍将是不可更改的。 Neither mutableCopy nor copy will perform a deep copy on the CONTENTS of the array however. 但是, mutableCopycopy都不会对数组的内容执行深层复制。 It is the ARRAY which becomes mutable or not, and not the CONTENTS of the objects held in the array. 是可变或可变的数组,而不是数组中保存的对象的内容。

Assuming the following: 假设以下内容:

@interface MyObject
- (int) state;
- (void) setState:(int) state;
@end

...

_nsarr = [NSArray arrayWithObject:[[MyObject alloc] initWithState]];
_nsmarr = [_nsarr mutableCopy];

At this point you have two distinct arrays, _nsarr and _nsmarr , one which isn't mutable, and one which is, HOWEVER, _nsarr[0] and _nsmarr[0] are still the same object, which means both that [_nsarr[0] setState:1] is valid, and that it has exactly the same effect as [_nsmarr[0] setState:1] 在这一点上,您有两个不同的数组_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

To copy the individual objects contained in the arrays, you need to create a "deep" copy of the array, which means to copy the contents (recursively) of the array as well as the array itself. 要复制数组中包含的各个对象,您需要创建一个数组的“深层”副本,这意味着(递归地)复制数组的内容以及数组本身。 There is no quick and easy way to create a deep copy of an array as it largely depends on how (if?) you can make a deep copy of the referenced objects. 没有快速简便的方法来创建数组的深层副本,因为它很大程度上取决于如何(如果?)来制作引用对象的深层副本。 Bharat presents one approach (marginally costly since it serializes and deserializes the objects, and requires that they adhere to NSCoding ) One approach might be something like: Bharat提出了一种方法(由于序列化和反序列化对象并要求它们遵守NSCoding ,因此成本NSCoding ),一种方法可能类似于:

_nsmarr = [NSArray withCapacity:[_nsarr count]];
for(MyObject* foo in _nsarr) {
    [_nsmarr addObject:[foo copy]];
}

Assuming that foo implements the NSCopying protocol, this is essentially identical to the initWithArray:copyItems: approach suggested by Milan: 假设foo实现了NSCopying协议,那么这基本上与Milan建议的initWithArray:copyItems:方法相同:

_nsmarr = [[NSMutableArray alloc] initWithArray:_nsarr copyItems:YES];

尝试这个

_nsMraa = [[NSArray alloc]initWithArray:_nsarr copyItems:YES];

If you need a true deep copy, such as when you have an array of arrays, you can archive and then unarchive the collection, provided the contents all conform to the NSCoding protocol. 如果您需要一个真正的深层副本(例如,当您有一个数组数组时),只要内容全部符合NSCoding协议,则可以存档然后取消存档该集合。 An example of this technique is shown below. 下面显示了此技术的示例。

  • A true deep copy 真正的深复制

     NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:oldArray]]; 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM