@ msaeed имеет правильный ответ, но стоит потратить немного больше времени на этот фрагмент кода, потому что он теряет память.
iPhone не поддерживает сборку мусора , поэтому важно понимать, как работает полуавтоматическое управление памятью в Objective-C. У Apple есть хорошая ссылка здесь , но суть ее в том, что вы несете ответственность за поддержание «сохранения количества» ваших объектов. При инициализации объекта методом экземпляра -init
(например, [[NSMutableArray alloc] init]
в вашем примере, но также и любым другим методом, начинающимся с "init", например [[NSMutableArray alloc] initWithCapacity:42]
, вновь инициализированный объект имеет счет сохранения 1. вызовы метода -retain
этого экземпляра увеличивают счет сохранения, а вызовы метода -release
экземпляра уменьшают счет. Когда счет достигает 0, объект освобождается, и дальнейшие попытки отправить ему сообщения приведут к исключениям нулевого указателя .
В случае исправленного кода @ msaeed, вот что происходит, строка:
- Новый экземпляр
NSMutableArray
выделен; вызывается метод -init
, который инициализирует экземпляр и устанавливает для счетчика хранения значение 1. Затем указатель positionIcons
устанавливается на адрес этого нового экземпляра.
- Метод
-insertObject:atIndex:
вызывается для positionIcons
, и все хорошо (также, по соглашению, добавление объекта в коллекцию, например NSMutableArray
, увеличивает счетчик сохранения этого объекта, идея состоит в том, что коллекция теперь имеет в в некотором смысле «владение» этим объектом и не хочет, чтобы он был освобожден из-под него).
- Выделен новый экземпляр
NSArray
, и указатель positionIcons
затем устанавливается на адрес этого нового экземпляра. Поскольку счетчик сохранения NSMutableArray
из первой строки по-прежнему 1, он не будет освобожден, и, поскольку вы потеряли ссылку на него, вы никогда не сможете вызвать -release
, чтобы удалить его из памяти. Вот твоя утечка.
По соглашению, существует разница в том, как вы управляете объектами, инициализированными с помощью -init
методов экземпляра, и методами класса, такими как +arrayWithObjects:
(в первом случае вы должны освободить объект самостоятельно, но во втором случае, объекту уже отправлено сообщение -autorelease
, и он будет освобожден при следующем проходе через цикл запуска программы, если вы не вызовете для него -retain
.