0

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

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

事实上,当我使用 mutablecopy

[self.cloneArray addObject:[[self.originalArray objectAtIndex:i] mutableCopy]];

我得到相同的结果。我很困惑。

数组类.h

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

@property (nonatomic, retain) NSMutableArray *originalArray;
@property (nonatomic, retain) NSMutableArray *cloneArray;

数组类.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]);
}

...

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
4

2 回答 2

8

你想这种方式太难了。

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

AnNSArray只是对象引用的集合。所以,如果你说:

NSArray *b = [NSArray arrayWithArray: a];

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

当您复制一个对象时,您正在创建一个与原始对象具有相同内部状态的新对象。即当你说NSMutableString *foo = [barString mutableCopy];, thenfoo是对字符串的引用;不同于barString.

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

于 2011-03-27T07:47:15.470 回答
5

你对正在发生的事情有误解。该replaceObjectAtIndex:withObject:调用不是修改数组中的对象,而是修改数组本身。在这一行之后:

[self.cloneArray replaceObjectAtIndex:0 withObject:@"blah"];

您已经替换了克隆数组中的对象,但根本没有更改原始数组。如果您实际修改了放入NSString数组中的对象,您可能会得到您期望的行为。但是,您将无法使用您在示例中放入原始数组的对象来执行此操作,因为它们是不可变的字符串对象。如果您将可变字符串插入其中,请使用相同的循环“克隆”您的数组,然后执行以下操作:

[[self.cloneArray objectAtIndex:0] appendString:@"some junk to append"];

您实际上会修改索引 0 处的字符串对象。由于两个数组仍然包含相同的对象,因此您将获得“通过更改克隆数组中的对象来修改原始数组”行为。

于 2011-03-27T07:42:41.800 回答