_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
. Однако даже это создаст мелкие копии содержащихся объектов, но есть много информации о том, как реализовать полную «глубокую» копию, если вам нужно это сделать.