将对象从一个NSMutableArray复制到另一个NSMutableArray

s20*_*der 0 objective-c nsmutablearray nscopying

我试图理解从一个NSMutableArray复制对象到另一个NSMutableArray.请考虑以下两种情况:1 - 将原始文件复制到克隆,其中克隆中的更改将影响原始文件.2 - 将原件复制到克隆,其中关闭中的更改不会影响原件.

首先,我尝试使用以下代码首先生成场景#1.根据我的理解,当复制数组不使用'mutablecopy'时,克隆数组将只保存指向原始字符串对象的指针.因此,如果我要将克隆的第一个元素更改为另一个对象,原始的第一个元素会改变得太对吗?......但这不是我得到的结果.为什么?

事实上,当我使用mutablecopy时

[self.cloneArray addObject:[[self.originalArray objectAtIndex:i] mutableCopy]];
Run Code Online (Sandbox Code Playgroud)

我得到了相同的结果.我很迷惑.

ArrayClass.h

@interface ArrayClass : NSObject {
    NSMutableArray *_originalArray;
    NSMutableArray *_cloneArray;
}

@property (nonatomic, retain) NSMutableArray *originalArray;
@property (nonatomic, retain) NSMutableArray *cloneArray;
Run Code Online (Sandbox Code Playgroud)

ArrayClass.m

@synthesize originalArray = _originalArray;
@synthesize cloneArray = _cloneArray;

_originalArray = [[NSMutableArray alloc] initWithObjects: @"one", @"two", @"three", @"four", @"five", nil];
_cloneArray = [[NSMutableArray alloc] initWithCapacity:[self.originalArray count]];

for (int i=0; i<5; i++) {
    [self.cloneArray addObject:[self.originalArray objectAtIndex:i]];
}

// make change to the first element of the clone array
[self.cloneArray replaceObjectAtIndex:0 withObject:@"blah"];

for (int n=0; n<5; n++) {
    NSLog(@"Original:%@ --- Clone:%@", [self.originalArray objectAtIndex:n], [self.cloneArray objectAtIndex:n]);
}
Run Code Online (Sandbox Code Playgroud)

...

2011-03-27 03:23:16.637 StringTest[1751:207] Original:one --- Clone:blah
2011-03-27 03:23:16.638 StringTest[1751:207] Original:two --- Clone:two
2011-03-27 03:23:16.639 StringTest[1751:207] Original:three --- Clone:three
2011-03-27 03:23:16.642 StringTest[1751:207] Original:four --- Clone:four
2011-03-27 03:23:16.643 StringTest[1751:207] Original:five --- Clone:five
Run Code Online (Sandbox Code Playgroud)

bbu*_*bum 8

你这么想是太难了.

在Objective-C中,您有对象的引用.一个NSString *foo;简单地定义了一个变量foo引用的NSString.如果你说NSString *bar = foo;,那么bar将引用任何对象foo所指的.不多也不少.

An NSArray只是对象引用的集合.所以,如果你说:

NSArray *b = [NSArray arrayWithArray: a];
Run Code Online (Sandbox Code Playgroud)

您正在创建一个数组b,其中包含对完全相同的对象集的所有相同引用a.如果修改引用的对象a,那将是完全相同的对象,b并且将反映修改.

当你复制一个对象,你要创建一个新的具有相同的内部状态作为原始对象.即,当你说NSMutableString *foo = [barString mutableCopy];,然后foo是一个字符串的引用; 不同于barString.

所以...在创建一个新数组时,问题是您希望数组包含与原始数组完全相同的内容,还是希望它包含一组可以修改的对象?


Car*_*rum 5

你对正在发生的事情有误解.该replaceObjectAtIndex:withObject:呼叫未在数组中修改的对象,它的修改数组本身.在此之后:

[self.cloneArray replaceObjectAtIndex:0 withObject:@"blah"];
Run Code Online (Sandbox Code Playgroud)

您已经替换了克隆数组中的对象,但您根本没有更改原始数组.如果您实际修改了放入数组中的NSString对象,则可能会获得您期望的行为.但是,在示例中,您将无法使用放入原始数组中的对象,因为它们是不可变的字符串对象.如果你在那里粘贴了可变字符串,使用相同的循环来"克隆"你的数组,然后按照以下方式做一些事情:

[[self.cloneArray objectAtIndex:0] appendString:@"some junk to append"];
Run Code Online (Sandbox Code Playgroud)

你实际上会修改索引0处的字符串对象.由于两个数组仍包含同一个对象,因此你可以通过改变克隆数组中的对象来获得"修改原始数组"的行为.