вызов [myString release] НЕ уменьшает [myString retainCount] - PullRequest
2 голосов
/ 09 июля 2010

У меня следующая ситуация, которая может привести к утечке памяти в приложении iPad.

У меня есть класс со строковым свойством ...

@property(nonatomic,retain) NSString * synopsis;

Я установил свойство строки из какого-либо HTTP-ответа, либо из JSON, либо из XML-ответа.

В этот момент счетчик сохранения объекта синопсиса равен 1.

Но у меня такая ситуация:

Я сохраняю синопсис в локальной базе данных sqlite, а затем хочу выпустить его из памяти, но у меня возникает странная ситуация, когда вызов [synopsis release] изнутри моего объекта не уменьшает счет сохранения до 0.

(void) save
{
  NSLog(@"synopsis before save retainCount=%d",[synopsis retainCount]);
  [self saveToDb:synopsis withKey:@"synopsis"];
  NSLog(@"synopsis after save retainCount=%d",[synopsis retainCount]);
  [synopsis release];
  NSLog(@"synopsis after release retainCount=%d",[synopsis retainCount]);
  synopsis=nil;
}

В консоли я получаю:

synopsis before save retainCount=1

synopsis after save retainCount=1

synopsis after release retainCount=1

Как это возможно? Я получаю тот же результат в симуляторе или на устройстве.

Ответы [ 3 ]

10 голосов
/ 09 июля 2010

НЕ ПОЛЬЗУЙТЕСЬ RETAINCOUNT!

Для людей это не точный показатель владения объектом.Вы не знаете, что вызывает retain и release за кулисами в рамках.

Управление памятью в Какао простое:

  1. Если вы alloc / init или copy объекта, убедитесь, что в какой-то момент вы вызываете release для него.
  2. Если вы хотите, чтобы объект находился рядом, позвоните retain - но обязательно вызовите release в какой-то момент тоже.
1 голос
/ 14 октября 2010

Это может помочь.Из документов о retainCount:

Важно: Этот метод обычно не имеет значения при отладке проблем управления памятью.Поскольку любое количество объектов каркаса могло сохранить объект для хранения ссылок на него, в то время как пулы автоматического выпуска могут содержать любое количество отложенных выпусков для объекта, маловероятно, что вы можете получить полезную информацию из этогоmethod.

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

• Статический анализатор LLVM / Clang обычно может обнаруживать проблемы с управлением памятью даже до запуска вашей программы.

• Инструмент Object Alloc вПриложение Instruments (см. Руководство пользователя Instruments) может отслеживать распределение и уничтожение объектов.

• Shark (см. Руководство пользователя Shark) также профилирует распределение памяти (среди множества других аспектов вашей программы).

1 голос
/ 09 июля 2010

Ваш третий NSLog, вероятно, вызывает retainCount для освобожденного объекта.

Тот факт, что вы видите значение 1, может иметь три причины:

  1. Сейчас по тому же адресу есть какой-то другой объект, у которого счетчик хранения равен единице.
  2. (более вероятно) освобожденный объект все еще там. Он отвечает на сообщение, возвращая счет сохранения, который будет равен единице, потому что он никогда не уменьшался до нуля (нет необходимости делать это когда-либо, поскольку освобожденный объект не нуждается в действительном числе хранения).
  3. Объект все еще находится там и имеет некоторое настраиваемое управление памятью, предотвращающее уменьшение значения retainCount.

Edit:

Чтобы проверить освобождение объектов (если вы хотите быть уверенными), вы всегда можете переопределить dealloc и установить точку останова или поместить туда сообщение журнала.

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