Установка объекта ноль против релиза + realloc - PullRequest
9 голосов
/ 09 марта 2009

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

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

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

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

или просто

myArr = nil;

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

Ответы [ 6 ]

21 голосов
/ 09 марта 2009

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

И, как говорит Георг, не имея возможности освободить ваш объект, эта память «просочилась».

6 голосов
/ 09 марта 2009

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

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

@property (readwrite, retain) NSMutableArray *myArray;

Затем заново инициализируйте его так:

[self setMyArray:[NSMutableArray array]];
5 голосов
/ 09 марта 2009

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

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

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

4 голосов
/ 02 декабря 2009

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

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

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

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

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

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

[myArr removeAllObjects];
1 голос
/ 14 марта 2009

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

1 голос
/ 09 марта 2009

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

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

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