复制或保留NSMutableArray中的addObject?

时间:2014-02-20 15:17:02

标签: ios objective-c nsmutablearray

当你将对象添加到集合中时,例如NSMutableArray,对象被复制,即值语义,还是被保留,即引用语义?

我在示例中感到困惑:

NSMutableString *testStr = [@"test" mutableCopy];
NSMutableArray *arrayA = [[NSMutableArray alloc] init];

[arrayA addObject:testStr];
NSLog(@"%@", arrayA);    // output: test

testStr = [@"world" mutableCopy];
NSLog(@"%@", arrayA);    // output: test

// testStr is copied - value semantics

NSMutableArray *testArr = [@[@1, @2] mutableCopy];
NSMutableArray *arrarB = [[NSMutableArray alloc] init];

[arrarB addObject:testArr];
NSLog(@"%@", arrarB);      // output: [1, 2]

[testArr addObject:@3];
NSLog(@"%@", arrarB);      // output: [1, 2, 3]

// testArr is retained - reference semantics

你可以看到:如果对象是NSMutableString,它看起来像是复制了对象 - 你更改对象不会影响数组中的对象。

但是,如果对象是NSMutableArray,则在更改对象时,也会更改数组中的对象 - 就像保留对象或通过引用传递一样。

我在这里遗漏了什么吗? 感谢。

5 个答案:

答案 0 :(得分:4)

在第一部分中,向数组添加对象不会复制。我们来看看你的代码:

在这里,您创建了NSMutableStringNSMutableArray

NSMutableString *testStr = [@"test" mutableCopy];
NSMutableArray *arrayA = [[NSMutableArray alloc] init];

然后将字符串添加到数组中:

[arrayA addObject:testStr];
NSLog(@"%@", arrayA);    // output: test

接下来,您要创建一个新的NSMutableString并将其分配给变量testStr,这只会使testStr指向新对象。它对您创建的第一个字符串没有影响:

testStr = [@"world" mutableCopy];
NSLog(@"%@", arrayA);    // output: test

这就是为什么你的第一个代码块如何工作的原因。

在你的第二个代码块中,似乎你已经理解为什么它的工作方式如何,但为了说清楚,testArr总是指向同一个数组,你也将其添加到{{1因此,打印arrarB的原因反映了您对arrarB所做的更改。

答案 1 :(得分:3)

集合保留而不是复制添加到它们的对象。

答案 2 :(得分:2)

字符串也保留在行中:

testStr = [@"world" mutableCopy];

您创建一个新字符串并将其副本分配给testStr局部变量,因此旧的保留字符串仍在表中

答案 3 :(得分:0)

代替:

testStr = [@"world" mutableCopy];

您可以尝试:

[testStr setString:@"world"];

这将修改“旧”字符串,而不是使testStr指向新对象

答案 4 :(得分:-1)

NSMutableString *testStr = [@"test" mutableCopy];
NSMutableArray *arrayA = [[NSMutableArray alloc] init];
[arrayA addObject:testStr];
NSLog(@"%@", arrayA);    // output: test

testStr = [@"world" mutableCopy];
NSLog(@"%@", arrayA);    // output: test

此处testStr未复制到arrayA。将testStr对象添加到数组后,testStr指针本身更改为引用其他对象(假设为“World”)。

与数组相同,您还可以将另一个字符串附加到testStr(而不是指向不同的字符串),您可以看到与testArr相同的结果。

  [testStr appendString:@" Test 2"];
`NSLog(@"%@", arrayA);`    // output: test Test 2