Установить объект на ноль после добавления их в контейнер? - PullRequest
0 голосов
/ 16 февраля 2011

Я думал, что NSArray / NSDictionary / NSSet и их изменяемые подклассы просто добавили указатель на объект, а не сам объект.

Итак, если мой «простой» объект установлен в nil после того, как я добавил его в контейнер, почему ссылка nil также не в массиве (контейнере)?

Вот код:

NSMutableArray *array = [[NSMutableArray alloc] init];

Simple *simple = [[Simple alloc] init];
[array addObject:simple];

//Array sends retain, lets release
[simple release], simple = nil;

NSLog(@"Simple = \"<Simple: %p>", simple);
NSLog(@"Array: %@", array);

[array release], array = nil;

Вот вывод:

2011-02-16 20:00:03.149 Allocations[5433:207] Simple = <Simple: 0x0>
2011-02-16 20:00:03.150 Allocations[5433:207] Array: (
    <Simple: 0x4d3d4e0>
)

Ответы [ 3 ]

3 голосов
/ 16 февраля 2011

NSArray добавляет указатель на объект . Чтобы отслеживать изменения в переменной, массив должен добавить указатель на самой переменной (помните, вы просто устанавливаете переменную на ноль, а не на объект). Может быть много переменных, указывающих на один и тот же объект, и переназначение их не изменит других.

Помните: указатели не волшебство. Это просто обычные переменные, значение которых является адресом памяти - в данном случае адресом памяти объекта. Два указателя на один и тот же объект не «связаны» более чем с двумя int s со значением 5. Изменение указателя не влияет на объект; чтобы воздействовать на объект, вы должны либо отправить ему сообщение, которое вызывает его изменение (например, [object setValue:6]), либо разыменовать указатель для прямого доступа к членам объекта (например, object->value = 6).

PS: не обращайтесь напрямую к членам объекта. Это плохо и хрупко и очень подвержено ошибкам. Я только что упомянул это здесь, чтобы объяснить, как работают указатели.

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

Установка simple = nil просто делает этот указатель нулевым.Он не удаляет объект, на который массив все еще имеет указатель.На момент выполнения ваших утверждений NSLog retainCount экземпляра Simple, на который указывает простой, будет равен единице.

Create simple

  • simple => (Простой экземпляр: retain count 1)

Добавить в массив

  • simple => (Простой экземпляр: сохранить счет 2)

  • [массив objectAtIndex: 0] => (Простой экземпляр: сохранить счет 2)

Отпустить простой

  • simple => (Простой экземпляр: сохранить счет 1)

  • [массив objectAtIndex: 0] => (Простой экземпляр: сохранить счетчик 1)

Установить простой = ноль

  • simple => nil

  • [массив objectAtIndex: 0] => (простой экземпляр: сохранить количество 1)

Разблокировать массив

  • (Простой экземпляр: сохранить счетчик 0, впоследствии уничтоженный)
0 голосов
/ 16 февраля 2011

NSArray содержит только указатель на добавленный объект, но это нормально - он указывает не на сам указатель simple, а на объект Simple, на который указывает simple. Таким образом, в вашем примере, после изменения того, на что указывает simple, массив все еще указывает на исходный объект Simple.

...