Установка объекта nil против release + realloc

Это не среда сбора мусора

У меня есть переменная экземпляра класса, которая в какой-то момент моей среды выполнения, мне нужно повторно инициализировать с другим набором данных, чем изначально был создан.

Гипотетически говоря, что, если у меня есть NSMutableArray или NSMutableDictionary, было бы более эффективно делать что-то вроде:

[myArr release];
myArr  = [[NSMutableArray alloc] init....];

или просто,

myArr = nil;

Будет ли myArr освобождать объект и оставить меня без указателя на память в памяти, чтобы я мог повторно использовать myArr?

Ответ 1

Если вы выполняете myArr=nil; самостоятельно, вы потеряете указатель, на который вы можете отправить сообщение release. Для объекта release нет волшебства.

И, как говорит Георг, не имея возможности выпустить свой объект, эта память "просочилась".

Ответ 2

Вы можете использовать свойство и получить почти необходимый синтаксис без утечки памяти.

Используйте этот синтаксис для объявления массива

@property (readwrite, retain) NSMutableArray *myArray;

Затем повторите инициализацию следующим образом:

[self setMyArray:[NSMutableArray array]];

Ответ 3

Если вы были на Mac OS, а не на iPhone OS, я бы сказал, что это зависит от того, активирован ли сборщик мусора или нет:

  • с GC: используйте myArr = nil;
  • без GC: используйте [myArr release];

К сожалению, на iPhone нет сборки мусора, поэтому, если вы не хотите утечки памяти, вам нужно освободить свой объект, как только он вам больше не понадобится.

Ответ 4

Первый кодовый блок в порядке. Тем не менее, второй блок не оставляет вас с массивом, который вы можете использовать, поэтому этого недостаточно. Половина исправляя этот блок, я думаю, вы имеете в виду:

myArr = nil;
myArr = [[NSMutableArray alloc] init....];

Однако это не означает, что вы хотите, потому что вы не выпускаете myArr. Если вы синтезировали сеттер для myArr, то вы можете получить поведение выпуска, которое вы хотите установить, равным нулю, используя setter (self.myArr) вместо прямого доступа к указателю (myArr). Полностью отредактируйте свой второй блок:

self.myArr = nil;
myArr = [[NSMutableArray alloc] init....];

Теперь у нас есть эквивалентные примеры кода, один из которых использует setter с nil для выпуска, а другой нет. Они одинаковы.

Если myArr является изменяемым массивом, как в этих примерах, наиболее эффективным методом является использование removeAllObjects, избегая всей работы по освобождению памяти только для ее возврата:

[myArr removeAllObjects];

Ответ 5

Один из способов понять разницу может заключаться в следующем: установка ссылки на объект на nil ничего не делает для объекта, он только делает что-то ссылку.

"Освобождение объекта" не "ничего", поэтому он этого не делает.:) На собранном мусором языке это может сделать это как побочный эффект отбрасывания ссылки, но в Objective C это не работает.

Ответ 6

Если вы хотите, чтобы reset содержимое NSMutableArray/NSMutableDictionary, вы также можете вызвать removeAllObjects, и у вас есть свежий массив /dict для работы.