insertObject не добавляет объект? - PullRequest
0 голосов
/ 17 июля 2009

Я пытаюсь пройти через Obj-C, чтобы создать игру для iPhone.

Я бы хотел создать массив объектов для последующего использования. Вот что я попробовал:

NSMutableArray      *positionIcons;
[positionIcons insertObject:annotation atIndex:0];
positionIcons = [NSArray arrayWithObjects:annotation, nil];

Строка insertObject оставляет счет в 0. Однако следующая строка корректно вставляет объект (и счет перемещается в 1). Что дает?

Ответы [ 2 ]

7 голосов
/ 17 июля 2009

Вам нужно инициализировать positionIcons, изменить код на:

NSMutableArray *positionIcons = [[NSMutableArray alloc] init];
[positionIcons insertObject:annotation atIndex:0];
positionIcons = [NSArray arrayWithObjects:annotation, nil];
4 голосов
/ 17 июля 2009

@ msaeed имеет правильный ответ, но стоит потратить немного больше времени на этот фрагмент кода, потому что он теряет память.

iPhone не поддерживает сборку мусора , поэтому важно понимать, как работает полуавтоматическое управление памятью в Objective-C. У Apple есть хорошая ссылка здесь , но суть ее в том, что вы несете ответственность за поддержание «сохранения количества» ваших объектов. При инициализации объекта методом экземпляра -init (например, [[NSMutableArray alloc] init] в вашем примере, но также и любым другим методом, начинающимся с "init", например [[NSMutableArray alloc] initWithCapacity:42], вновь инициализированный объект имеет счет сохранения 1. вызовы метода -retain этого экземпляра увеличивают счет сохранения, а вызовы метода -release экземпляра уменьшают счет. Когда счет достигает 0, объект освобождается, и дальнейшие попытки отправить ему сообщения приведут к исключениям нулевого указателя .

В случае исправленного кода @ msaeed, вот что происходит, строка:

  1. Новый экземпляр NSMutableArray выделен; вызывается метод -init, который инициализирует экземпляр и устанавливает для счетчика хранения значение 1. Затем указатель positionIcons устанавливается на адрес этого нового экземпляра.
  2. Метод -insertObject:atIndex: вызывается для positionIcons, и все хорошо (также, по соглашению, добавление объекта в коллекцию, например NSMutableArray, увеличивает счетчик сохранения этого объекта, идея состоит в том, что коллекция теперь имеет в в некотором смысле «владение» этим объектом и не хочет, чтобы он был освобожден из-под него).
  3. Выделен новый экземпляр NSArray, и указатель positionIcons затем устанавливается на адрес этого нового экземпляра. Поскольку счетчик сохранения NSMutableArray из первой строки по-прежнему 1, он не будет освобожден, и, поскольку вы потеряли ссылку на него, вы никогда не сможете вызвать -release, чтобы удалить его из памяти. Вот твоя утечка.

По соглашению, существует разница в том, как вы управляете объектами, инициализированными с помощью -init методов экземпляра, и методами класса, такими как +arrayWithObjects: (в первом случае вы должны освободить объект самостоятельно, но во втором случае, объекту уже отправлено сообщение -autorelease, и он будет освобожден при следующем проходе через цикл запуска программы, если вы не вызовете для него -retain.

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