ios - newArray = array 和 newArray = [array copy] 有什么区别?

标签 ios objective-c copy nsarray

我有这行代码:

- (void)redrawGraphWithArray:(NSArray *)array {
    _graphView.graphPoints = [array copy];
    [_graphView setNeedsDisplay];
}

graphPoints 也是 NSArray。

如果我使用

_graphView.graphPoints = array;

图表看起来一样,没有问题。

我想知道两者之间的区别

_graphView.graphPoints = [数组副本]

_graphView.graphPoints = array;

谢谢。

最佳答案

_graphView.graphPoints = array; 将 graphPoints 指定为与​​原始对象相同的数组。您只是在创建另一个指向完全相同内存的指针。例如,这将会发生:

NSMutableArray *array = [[NSMutableArray alloc] init];
array[0] = @{@"x": @1, @"y": @2};
array[1] = @{@"x": @1, @"y": @3};
_graphView.graphPoints = array;

// Now let's make some changes to the original array
// Note that I used an NSMutableArray to explain fully the differences between
// the two assignment types.
array[0] = @{@"x": @1, @"y": @1}; // With an NSArray you wouldn't be able to do this
array[1][@"y"] = @5;              // But this can still happen

// What happens to graphPoints?
_graphView.graphPoints[0]; // <== {x: 1, y: 1}
_graphView.graphPoints[1]; // <== {x: 1, y: 5}

在本例中,graphPoints 指向与 array 完全相同的对象,因此两者保持完全相同。代码示例中没有对此进行说明,但请务必记住,这种“相同性”指向两个方向,因此更改 graphPoints 也会更改 array

另一方面,[array copy] 创建了一个新的数组对象,它是原始数组对象的副本,所以上面的代码会有不同的结果:

NSMutableArray *array = [[NSMutableArray alloc] init];
array[0] = @{@"x": @1, @"y": @2};
array[1] = @{@"x": @1, @"y": @3};
_graphView.graphPoints = [array copy];

// Now let's make the same changes to the original array
array[0] = @{@"x": @1, @"y": @1};
array[1][@"y"] = @5;

// What happens to graphPoints?
_graphView.graphPoints[0]; // <== {x: 1, y: 2}
_graphView.graphPoints[1]; // <== {x: 1, y: 5}

第一个对象在 graphPoints 中没有改变,因为我们在 array 中写入了一个全新的对象。由于 graphPoints 现在是一个副本,因此它没有受到影响。

但是,第二个对象确实发生了变化,因为我们没有将新对象写入 array ,而是修改了现有对象,该对象包含在两个数组中。这说明了对象复制的一个重要微妙之处。这就是所谓的“浅”副本,这意味着容器会被复制,但其内容不会。您最终得到两个数组,但只有一组包含的对象。

通过确保包含的对象都实现 NSCopying 协议(protocol),也有相对简单的方法来复制所有包含的对象(如果你只是使用 Foundation 类,如 NSDictionaryNSArrayNSNumberNSString ,你不需要需要担心,因为这已经为您完成了)并在 - initWithArray:copyItems: 上使用 NSArray 初始化程序。然而,即使这也会创建所包含对象的浅拷贝,但如果您需要的话,有很多关于如何实现完整“深”拷贝的信息。

关于ios - newArray = array 和 newArray = [array copy] 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35081981/

相关文章:

iphone - 如何在 iOS 上的 OpenGL ES 1.0 中使用顶点缓冲对象 (VBO) 而不是调用 glDrawArrays 数千次?

ios - 如何在启动时实现像 UBER 应用程序文本这样的动画

objective-c - IBAction 与按钮连接但需要一个 void

java - 使用 putAll() 复制树状图的 Java 树状图

c# - 我们如何将数据表的数据列的数据复制到另一个数据表?

ios - Facebook SDK 启动到 Safari 而不是应用程序 (Swift)

占位符 View 和导航栏之间的 iOS 空间

javascript - iPad 2 上的 Safari 动态加载图像导致内存泄漏

objective-c - 告诉 UIPageViewController 何时滚动(用于图像的视差滚动)

c# - 流畅的 nhibernate 复制一个完整的实体