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

时间:2016-01-29 10:18:54

标签: ios objective-c copy nsarray

我有这行代码:

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

graphPoints 也是NSArray。

如果我使用

_graphView.graphPoints = array;

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

我想知道

之间的区别

_graphView.graphPoints = [array copy]

_graphView.graphPoints = array;

感谢。

3 个答案:

答案 0 :(得分:1)

_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完全相同的对象,因此两者保持完全相同。它没有在代码示例中说明,但记住这个&#34;同一性&#34;非常重要。指向两个方向,因此对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,而是修改了包含的现有对象两个数组。这说明了对象复制的一个重要细微之处。这就是所谓的&#34;浅&#34;复制,这意味着容器被复制,但其内容不复制。最终得到两个数组,但只有一组包含的对象。

通过确保所包含的对象都实现NSCopying协议(如果您只是使用FoundationNSDictionary,还有相对简单的方法来复制所有包含的对象。 1}},NSArrayNSNumberNSString,您不必担心,因为这已经为您完成了)并使用了- initWithArray:copyItems:初始值设定项NSArray。然而,即使这样也会创建包含对象的浅拷贝,但是有很多关于如何实现完整&#34;深度&#34;复制,如果你需要这样做。

答案 1 :(得分:0)

[array copy]将创建新的数组实例(具有相同的内容)并将其分配给graphpoints。就像你只是分配数组一样,graphpoints将具有与对象数组相同的引用。也就是说,两者都指向同一个对象。因此,如果您更改数组对象,那么它也将更改图形点。但如果你使用副本就不会这样。

答案 2 :(得分:0)

这是一个不成熟的优化。

主要区别:第一种方法导致自动释放&#34;复制&#34;当你拥有在第二行创建的对象时,你不会拥有并且不必释放。顺便说一下,这两个数组都是不可变的。