Objective-C = operator vs stringWithString / arrayWithArray

时间:2014-02-19 14:38:14

标签: objective-c

我是obj-c开发的新手,但部分具有C开发的背景。这可能是一个菜鸟问题,但我无法在其他地方得到确切的答案。这些数组和字符串的片段以及可能的其他类型的对象之间有什么区别:

NSArray *original = [NSArray arrayWithObjects:someObjects,nil];
//Case 1
NSArray *copy1 = original;
//Case 2
NSArray *copy2 = [NSArray arrayWithArray:original];

和字符串

NSString *original = @"aString";
//Case 1
NSString *copy1 = original;
//Case 2
NSString *copy2 = [NSString stringWithString:original];

如果我对copy1和copy2进行更改,它们会反映在原始对象上吗?并且相同的规则是否适用于其他对象类型?

4 个答案:

答案 0 :(得分:3)

第二个代码段针对NSString第一个代码段为NSArray执行的操作。行为没有区别,因为Cocoa中的NSStringNSArray对象都是不可变的

当你打电话给[NSString stringWithString:original]时,Cocoa足够聪明,不会创建一个新对象:这个决定背后的原因是,由于original无法更改,所以你无法区分副本从原来的。 [NSArray arrayWithArray:original]也是如此,因为你得到了同样的实例。

注意:如果someObjects是可变的,可以通过修改对象来分辨数组与其深层副本,并查看它是否在其他位置发生变化。但是,arrayWithArray:方法会生成“浅”副本,因此即使数组中的对象是可变的,也无法检测到差异。

答案 1 :(得分:2)

你的问题实际上是关于指针指向的对象。当你说make changes to copy1 and copy2 later时,我猜你的意思是指针内容,而不是指针引用的对象。这是一种相当实用的思考方式,但它非常重要。

在您的示例中,数组/字符串部分无关紧要,因为您没有对这些对象执行任何操作,您只是使用指向这些对象的指针。

original指向一个对象。 copy1指向同一个对象。 copy2指向另一个对象(但在这种情况下,它是第一个对象的副本)。

答案 2 :(得分:2)

copy1不是副本,而是指向与original相同内存的另一个指针。 copy2实际上是一个副本,指向不同的记忆。

如果你修改copy1(假设它是可变的,你的示例代码不是),你也在修改original,因为它们指向同一块内存。

如果修改copy2original应保持不变(一般而言)。在您的数组示例中,数组original和数组copy2中的对象是相同的。所以在这种情况下,你有两个数组,但它们中有相同的对象。

答案 3 :(得分:0)

NSArrays和NSStrings是不可变的,因此您无法更改它们。

您无法在NSArray中添加或删除对象,但如果您更改数组中的某个对象,它将在其副本中更改,因为NSArray包含指向它的指针。