Удаление объекта из NSArray автоматически освобождает его память? - PullRequest
0 голосов
/ 19 октября 2011
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

myClass *obj = [[myClass alloc] init];

NSArray *ar = [NSArray array];

[ar addObject: obj];

[ar removeObject: obj];

[pool drain];

Будет ли удаление объекта из массива NSArray автоматически освобождать его память, которую я ранее выделил ??Ответ, кажется, да из того, что я нашел из разных источников.Проблема в том, что если я проверяю утечки памяти, xcode все еще жалуется, что obj не был выпущен.Так что же на самом деле происходит?

Ответы [ 3 ]

3 голосов
/ 19 октября 2011

Коллекции сохраняют объекты, которые вы добавляете к ним, требуя временного владения. Когда вы удаляете элемент из коллекции, он освобождает объект (и его временное требование). Другими словами, количество сохранений будет таким же, как до добавления объекта в коллекцию и после его удаления.

Если этот счетчик равен 0, память восстанавливается.

В своем коде вы выделяете объект и заявляете о праве собственности на него. Это означает, что он имеет счет удержания 1.

Затем вы добавляете его в массив. Массив сохраняет объект, принимая временное владение и увеличивая его счетчик хранения до 2.

Затем вы удаляете объект из массива. Массив освобождает объект и отказывается от любых претензий на право собственности, в результате чего количество сохраняемых данных уменьшается до 1.

Поскольку память не восстанавливается до тех пор, пока значение счетчика не вернется к 0 (никто не претендует на объект), память вашего объекта не восстанавливается.

Если вы автоматически освободили объект до добавления его в массив или вызвали release для объекта после того, как удалили его (но не оба!), То счетчик сохранения будет равен 0, и память будет освобождена.

2 голосов
/ 19 октября 2011

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

Но ваша проблема в приведенном вышеСценарий заключается в том, что после добавления объекта в массив вы не смогли освободить СВОЕ удержание объекта (из-за alloc / init).Вставьте [obj release] после [ar addObject:obj].

(также обратите внимание, что в вашем примере весь массив будет «пуфить» при опустошении пула автоматического выпуска.)

2 голосов
/ 19 октября 2011

Нет, вы распределяете это -> сохраняете счет 1

Вы добавляете его в массив, который отправляет объект другому объекту -> 2

Вы удаляете объект из массива, а массив отправляет релиз -> 1

... так что теперь счетчик хранения возвращается к 1, что является вашим первоначальным резервным распределением, поэтому вам нужно освободить его, чтобы освободить память.

...