изменение элементов массива после поверхностного копирования массива - PullRequest
2 голосов
/ 16 апреля 2011

В книге «Программирование в Objective C2» (Стивен Кочан) был следующий массив:

NSMutableArray *arr1 = [NSMutableArray arrayWithObjects:
    @"one, @"two", @"three", nil];

и другой массив, объявленный следующим образом:

NSMutableArray *arr2;

и мелкая изменяемая копияпроисходит следующим образом:

arr2 = [arr1 mutableCopy];

в соответствии с учебником, arr2 теперь содержит новый массив, но со ссылками на объекты arr1 объекты не являются реальными копиями для объектов в массиве.

В книге сказано, чтобы изменить первый элемент arr2, не затрагивая первый элемент arr1, напишите следующие строки:

NSMutableString *mStr = [NSMutableString stringWithString:[arr2 objectAtIndex:0]];
[mStr appendString: @"ONE"];
[arr2 replaceObjectAtIndex: 0 withObject: mStr];

Кто-нибудь может объяснить, почему первый элемент arr2 затронул только первый элемент arr1, но не первыйтоже?

1 Ответ

2 голосов
/ 16 апреля 2011

У вас есть два разных массива.Вот и ответ:).

Подробно:

  • arr1 и arr2 различны
  • элементы внутри них указывают на одни и те же объекты

При замене первого объекта arr2 вы не перезаписываете предыдущий объект.И поскольку оба массива не совпадают (были только элементы), замена происходит только для arr2, а не для arr1.

Опять более подробно:

Вынужно понимать, что такое массив.Это всего лишь список указателей на объекты.При создании массива с 3 объектами у вас есть массив с 3 указателями на 3 объекта.Когда вы создаете копию этого массива, вы создаете не копию объектов, а копию трех указателей.Таким образом, ваш arr2 будет другим объектом со своими собственными 3 указателями, указывающими на 3 элемента (obj1 .. obj3).Теперь, когда вы делаете replaceObjectAtIndex:withObject, вы только обмениваетесь указателем arr2 с другим (указывающим на другой объект (mStr). Поскольку оба массива (arr1 и arr2) не являются одинаковыми объектами (вы создали копию), это будет тольковлияет на arr2 (опять же: вы только изменили указатель на arr2 - вы вообще не изменили obj1 !!).

Когда вы пишете [obj1 appendString:@"changed"], это повлияет на оба массива, поскольку оба указывают на obj1.

Надеюсь, это прояснит для вас!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...