繁体   English   中英

Objective-C:复制数组,仅在复制中修改元素(对象)

[英]Objective-C: Copy Array, Modify Element (Object) in the Copy ONLY

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

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

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

到目前为止似乎,因为副本只是复制引用 (或指针),更改索引2处的对象将在副本原始文件中更改它。

那有意义吗?

NSArray *originalArray = @[object1, object2];

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

NSMutableArray *originalArrayCopy = [NSMutableArray arrayWithArray:originalArray];

NSArray *originalArrayCopy = [originalArray copy];

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

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

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

如果数组的元素符合NSCopying协议,则可以执行以下操作:

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

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

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

没有内置的公共消息可以做到这一点。 你可以像这样手动完成:

NSMutableArray *copy = [[NSMutableArray alloc] initWithCapacity:originalArray.count];
for (id element in originalArray) {
    [copy addObject:[element mutableCopy]];
}

这使得第一个NSArray的深层副本成为第二个NSMutableArray:

NSArray *firstArray = [NSArray arrayWithObjects:@"foo", @"bar",nil];
NSMutableArray *secondArray = [[NSMutableArray alloc]initWithArray:firstArray copyItems:YES];

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

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

你可以用这种方式制作任何对象的深层副本

NSArray *originalArray = @[object1, object2];
NSMutableArray *deepCopy = [NSkeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject: originalArray]];

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

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

是的,没有理由为什么不可变数组中的对象也应该是不可变的。

暂无
暂无

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

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