当你将对象添加到集合中时,例如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
,则在更改对象时,也会更改数组中的对象 - 就像保留对象或通过引用传递一样。
我在这里遗漏了什么吗? 感谢。
答案 0 :(得分:4)
在第一部分中,向数组添加对象不会复制。我们来看看你的代码:
在这里,您创建了NSMutableString
和NSMutableArray
:
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