4

在问这个问题之前,我已经阅读了许多 SO 帖子,我猜这个答案就在某个地方,但我没有看到。我是 Objective-C 的新手,我正在尝试做一个我无法弄清楚的(看似)简单的动作。

一般的想法是我有一个NSArray填充对象(特别是 type UIImageView)。我想复制那个数组,我已经做了很多方法(都成功)。

复制后,我现在有两个数组。我想修改一个对象,比如索引 2,在副本中。

到目前为止,似乎因为副本只是复制引用(或指针),所以更改索引 2 处的对象将同时更改副本原始对象。

那有意义吗?

NSArray *originalArray = @[object1, object2];

我尝试复制此数组的方式,以便实现我想要的:

NSMutableArray *originalArrayCopy = [NSMutableArray arrayWithArray:originalArray];

NSArray *originalArrayCopy = [originalArray copy];

NSMutableArray *originalArrayCopy = [[NSMutableArray alloc] initWithArray:originalArray];

而且似乎在每种情况下,从副本修改对象也会在原始对象中修改它。

注意:虽然NSArray显然是不可变的,但我原始数组中的对象可变的。

4

4 回答 4

12

如果你的数组元素符合NSCopying协议,你可以这样做:

NSMutableArray *copy = [[NSMutableArray alloc] initWithArray:originalArray copyItems:YES];

这具有发送copy到原始数组的每个元素的效果,将副本存储在新数组中。

如果每个元素在收到copy消息时返回一个新的、可变的副本,这很好。但是,一些 Foundation 类(如NSMutableArrayNSMutableString)在收到copy消息时会返回不可变的副本。如果您的元素属于此类,则需要改为发送mutableCopy消息。

没有内置的公共信息可以做到这一点。您可以像这样手动执行此操作:

NSMutableArray *copy = [[NSMutableArray alloc] initWithCapacity:originalArray.count];
for (id element in originalArray) {
    [copy addObject:[element mutableCopy]];
}
于 2013-05-31T21:39:18.450 回答
1

这将第一个 NSArray 的深层复制到第二个 NSMutableArray:

NSArray *firstArray = [NSArray arrayWithObjects:@"foo", @"bar",nil];
NSMutableArray *secondArray = [[NSMutableArray alloc]initWithArray:firstArray copyItems:YES];
于 2013-05-31T21:48:54.133 回答
1

只要您要复制的对象实现 NSCoding 协议

(void)encodeWithCoder:(NSCoder *)encoder;
(id)initWithCoder:(NSCoder *)decoder;

您可以通过这种方式制作任何对象的深层副本

NSArray *originalArray = @[object1, object2];
NSMutableArray *deepCopy = [NSkeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject: originalArray]];
于 2013-05-31T22:07:59.040 回答
0

是的,所有这些只会复制数组。您复制的数组仍将引用相同的对象。

我不认为(或只是不知道如何)您可以一次复制所有包含的对象。我想您将不得不遍历原始数组中的对象,复制每个对象并将其副本添加到新创建的最初为空的可变数组中。如何复制这些对象很大程度上取决于这些对象的性质和复制它们的目的。

是的,不可变数组中的对象也没有理由不可变。

于 2013-05-31T21:37:21.663 回答