Управление памятью в объективе-c - PullRequest
2 голосов
/ 11 марта 2010

У меня есть этот код в одном из моих классов:

- (void) processArray
{

   NSMutableArray* array = [self getArray];
   . . .
   [array release];
   array  = nil;
}


- (NSMutableArray*) getArray
{
   //NO 1:
   NSMutableArray* array = [[NSMutableArray alloc]init];

   //NO 2:
   NSMutableArray* array = [NSMutableArray array];
   . . .
   return array;
}

NO 1: я создаю массив и возвращаю его.В методе processArray я освобождаю его.

NO 2: я получаю массив, просто вызывая array.Поскольку я не владелец этого, мне не нужно выпускать его в методе processArray.

Какая лучшая альтернатива, NO 1 или NO 2?Или есть лучшее решение для этого?

Ответы [ 3 ]

7 голосов
/ 11 марта 2010

Метод должен возвращать автоматически освобожденный массив, NO 2 - лучший выбор. Причина этого заключается в том, что при вызове метода с

   NSMutableArray* array = [self getArray];

В соответствии с соглашением не нужно освобождать массив. Если вы хотите завладеть им, вы сохраняете его, но в противном случае вам не нужно заботиться об этом. В Какао вы только вступаете во владение, явно отправляя alloc или retain или copy (или new). Поскольку метод processArray этого не делает, он не должен заботиться об освобождении массива.

Таким образом, вы должны использовать NO 2, а также вы должны удалить эти две строки:

[array release];
array  = nil;
1 голос
/ 11 марта 2010

Если массив и его содержимое используют много памяти или его много раз, вы захотите освободить их сразу, поэтому используйте опцию 1. В соответствии с рекомендациями Objective-C, вы захотите поставить префикс в этом случае слово «новый» для имени подпрограммы вместо «получить».

Если, с другой стороны, вы хотите уменьшить количество строк кода, которые говорят просто [выпуск массива]; или аналогичный, тогда используйте вариант 2.

Это просто баланс между сокращением строк кода и сокращением ненужного использования временной памяти.

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

НТН

EDIT

Ах - я исправлен. Чтение версии iPhone Руководства по программированию управления памятью для какао Я вижу, что в руководствах iPhone должен использоваться префикс "new ... "так, например," newArray "в этом случае, если вызывающая сторона должна выпустить вручную, а НЕ префикс" create ... ". «Создание» может относиться либо к созданию объектов, выпущенных вручную, либо к автоматически выпущенным объектам, и поэтому будет неоднозначным. Текст исправлен выше.

0 голосов
/ 11 марта 2010
- (void) processArray
{

   NSMutableArray* array = [[self getArray] retain];
   //Now you are the owner of array, so you take care to release it

   . . .

   [array release];
   array  = nil;
}


- (NSMutableArray*) getArray
{
   //create a new array 
   //temporarily the method owns the array
   NSMutableArray* array = [[NSMutableArray alloc]init];

   //fill in here with elements or what you want
   ..........

   [array autorelease];
   //autorelease here says "I don't own the result
   //if anyone cares about it, he should retain it himself

   return array;
}

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

Всегда полезно запустить статический анализатор Klang для этих проблем, когда вы не уверены в своем сохраняющем / освобождающем коде: http://clang -analyzer.llvm.org /

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