Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective-C=运算符vs stringWithString/arrayWithArray_Objective C - Fatal编程技术网

Objective-C=运算符vs stringWithString/arrayWithArray

Objective-C=运算符vs stringWithString/arrayWithArray,objective-c,Objective C,我是obj-c开发的新手,但在一定程度上有c开发的背景。这可能是一个noob问题,但我在其他地方找不到确切的答案。数组、字符串和其他类型对象的这些代码段之间有什么区别: NSArray *original = [NSArray arrayWithObjects:someObjects,nil]; //Case 1 NSArray *copy1 = original; //Case 2 NSArray *copy2 = [NSArray arrayWithArray:original]; 弦呢

我是obj-c开发的新手,但在一定程度上有c开发的背景。这可能是一个noob问题,但我在其他地方找不到确切的答案。数组、字符串和其他类型对象的这些代码段之间有什么区别:

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进行更改,它们会反映在原始对象上吗?同样的规则也适用于其他对象类型吗?

您的问题实际上是关于指针指向的对象。当你说以后对copy1和copy2进行更改时,我想你指的是指针内容,而不是指针引用的对象。这是一种相当实用的思维方式,但它并不重要

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


original
指向一个对象
copy1
指向同一对象
copy2
指向不同的对象(但在本例中,它是第一个对象的副本)。

第二个代码段对
NSString
的作用与第一个代码段对
NSArray
的作用相同。行为上没有区别,因为Cocoa中的
NSString
NSArray
对象都是不可变的

当您调用
[NSString stringWithString:original]
时,Cocoa足够聪明,不会创建新对象:此决策背后的原因是,由于
original
无法更改,因此您无法区分副本和原始副本。
[NSArray arrayWithArray:original]
也是如此,因为您得到了相同的实例


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

nsarray和nsstring是不可变的,因此您无法更改它们


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

copy1
不是副本,而是指向与原始
相同内存的另一个指针
copy2实际上是一个副本,指向不同的内存块

如果您修改
copy1
(假设它是可变的,而示例代码不是),那么您也在修改
原始的
,因为它们指向同一块内存


如果您修改了
copy2
原件应保持不变(一般来说)。在您的数组示例中,我相信数组
original
和数组
copy2
中的对象是相同的。因此,在本例中,您有两个数组,但它们中有相同的对象。

因为原始字符串是不可变的,所以copy2不是一个不同的对象,而是完全相同的实例。@NikolaiRuhe,在本例中,是的,但我觉得这使主题复杂化了。我可以扩展和考虑可变对象,如果它有助于<代码>某些对象< /代码>可更改性与<>代码> ARAYAWAsARS/<代码>无关,则创建一个新的实例。只考虑接收器。拷贝总是浅的。@NikolaiRuhe我的观点是,如果对象是可变的,你可以判断是否已经制作了深拷贝。如果它是不可变的,就没有合法的方法来区分它们。两个数组(原始数组和从
arrayWithArray
返回的数组)永远无法区分,因为它们是同一个实例(如果在本例中,原始数组是不可变的)。这不取决于元素。我想,现在我明白你的意思了。我被深拷贝和浅拷贝搞糊涂了(因为Cocoa只知道浅拷贝),问题是浅拷贝和根本没有拷贝。唉,我只能投一次票:(
copy2
没有指向不同的内存块。它是同一个实例。@NikolaiRuhe抱歉,不是。
+arrayWithArray
返回一个新数组,填充了它的参数内容。快速测试也证明了这一点。哦,我错了。我当时的印象是
arrayWithArray:
会进行同样的优化作为
copy
。感谢您指出这一点!对于理解基本指针语义和对象标识而言,
NSArray
NSString
都是不好的例子,因为它们经过优化,在无法更改原始指针语义和对象标识时不会创建副本(不可变)。您无法更改由copy1或copy2指向的字符串;它们是不可变的。但您可以为copy1或copy2指定新值。