2016-01-29 5 views
0

У меня есть эти строки кода:В чем разница между newArray = array и newArray = [array copy]?

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

graphPoints является NSArray тоже.

Если я использую

_graphView.graphPoints = array; 

график выглядит так же, и нет никаких проблем.

Я хочу знать, что разница между

_graphView.graphPoints = [array copy] и

_graphView.graphPoints = array;

Спасибо.

ответ

0

[array copy] создаст новый экземпляр массива (с тем же содержимым) и назначит его графическим точкам. Где, как если бы вы просто назначали массив, точки графа будут иметь такую ​​же ссылку, что и для массива объектов. То есть оба указывают на один и тот же объект. Таким образом, если вы измените объект массива, то он также изменит графические точки. Но это не так, если вы используете копию.

0

Это преждевременная оптимизация.

Главное отличие: первый подход приводит к автореализованной «копии», которой вы не являетесь, и ее не нужно выпускать, тогда как вы владеете объектом, созданным во второй строке. Между прочим, оба массива будут неизменными.

1

_graphView.graphPoints = array; назначает графовые точки того же массива, что и исходный объект. Вы просто создаете другой указатель на ту же самую память. Так, например, это будет происходить:

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 (если вы используете только Foundation классы, как NSDictionary, NSArray, NSNumber, NSString, вы не» t нужно беспокоиться, поскольку это уже сделано для вас) и используя инициализатор - initWithArray:copyItems: на NSArray. Однако даже это создаст мелкие копии содержащихся объектов, но есть много информации о том, как реализовать полную «глубокую» копию, если вам нужно это сделать.

Смежные вопросы