所以有一段时间我一直在研究这个应用程序 - 其中包含一个类似文件夹的对象结构,这些对象具有可以包含相同类型对象的数组属性,而数组又可以包含更多该对象,等等. 这些对象称为组。在共享数据类中,我有一个名为 mainGroup 的母组对象,以及一个名为 selectedGroup 的数据类属性,以方便数据的显示。这些组对象可以修改,因此在相当长的一段时间内,我尝试开发一种解决方案,以获取通过所有数组到达所需对象的路径,同时对复制以及分配一个数组等于other 不会创建深拷贝,只是某种引用。该代码在逻辑上是合理的,但在一段时间后,我注意到删除 selectedGroup 数组属性中的内容对实际主副本具有相同的效果,这对我的应用程序做了一些奇怪的事情。
我做了一些谷歌搜索,发现我实际上并没有创建一个全新的数组,只是以某种方式引用它。不过,我对下一部分仍然感到困惑。我认为将一个数组设置为等于另一个数组与在其上调用 copy 具有相同的效果 - 当我替换或删除一个数组中的对象时,另一个数组会受到影响。那么,当您将两个数组设置为彼此相等时,编译器到底在做什么呢?难道它不应该只用指向旧数组中对象的指针填充新数组,而不仅仅是引用数组本身吗?为什么当对 NSStrings 等对象执行相同的操作时,您没有看到相同的效果?最后,还有哪些其他对象具有与 NSArray 相同的行为?
最佳答案
So what exactly is the compiler doing when you set two arrays equal to each other?
Objective-C 中的许多不可变类实现了 -copy
,这样该方法只需保留原始对象并返回指向它的指针。例如,如果您复制 NSString
的实例,您将获得指向同一对象的指针。因为该对象是不可变的,所以无论您是否实际创建它的副本都无关紧要——该对象无法更改,并且副本将完全相同,因此指向原始对象的另一个指针的工作方式完全相同就像副本一样。再次保留该对象可确保至少在调用者处理完该对象之前该对象不会被销毁。
其他类也是如此,例如 NSArray
以及可能的 NSData
、NSDate
、NSNumber
、也许还有其他。完整的列表并不是真正必要的,因为行为应该对客户透明。
如果您确实使用 NSArray
实例,则很难理解您所描述的问题是如何出现的。您无法在 NSArray 中添加或删除对象——这就是类不可变的含义。听起来您实际上正在处理一个可变数组(NSMutableArray
),并且该类(以及其他类似 NSMutableString
等)在您调用时确实会创建实际副本-复制
。
听起来您实际上并没有复制正在使用的数组,而只是复制了指向数组的指针。例如:
NSArray *array1 = [NSMutableArray arrayWithObjects:@"foo", @"bar", nil];
NSArray *array2 = array1;
现在,上面的代码没有复制第一个数组。你得到的是一个数组,有两个指向它的变量。如果您对 array1
进行更改,您也会看到该更改也反射(reflect)在 array2
中,因为 array1
和 array2
> 实际上只是同一个数组的两个名称。如果您想要副本,可以这样做:
NSArray *array3 = [array1 copy];
现在,让我们做出改变:
NSLog(@"Size of array1: %ld", [array1 count]); // 2
NSLog(@"Size of array2: %ld", [array2 count]); // 2
NSLog(@"Size of array3: %ld", [array3 count]); // 2
[array1 removeObjectAtIndex:1];
NSLog(@"Size of array1: %ld", [array1 count]); // 1
NSLog(@"Size of array2: %ld", [array2 count]); // 1
NSLog(@"Size of array3: %ld", [array3 count]); // 2
关于ios - NSObjects iOS 的复制和引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31757990/