Понимание подсчета ссылок с Какао и Objective-C - PullRequest
121 голосов
/ 09 августа 2008

Я только начинаю смотреть на Objective-C и Cocoa, чтобы поиграть с iPhone SDK. Я достаточно комфортно отношусь к концепции C malloc и free, но схема подсчета ссылок в Cocoa меня довольно смущает. Мне сказали, что это очень элегантно, когда ты это понимаешь, но я еще не перебрал горб.

Как работают release, retain и autorelease и каковы соглашения об их использовании?

(Или, если не получилось, что вы прочитали, что помогло вам получить это?)

Ответы [ 14 ]

4 голосов
/ 09 августа 2008

Ответ NilObject - хорошее начало. Вот некоторая дополнительная информация, относящаяся к ручному управлению памятью ( требуется на iPhone ).

Если вы лично alloc/init объект, он имеет счетчик ссылок 1. Вы несете ответственность за очистку после него, когда он больше не нужен, либо позвонив [foo release] или [foo autorelease]. release очищает его сразу же, тогда как autorelease добавляет объект в пул autorelease, который автоматически освобождает его позднее.

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

Если вы приобрели объект, для которого вы не вызывали alloc / init, например:

foo = [NSString stringWithString:@"hello"];

но вы хотите держаться за этот объект, вам нужно вызвать [foo retain]. В противном случае, возможно, он получит autoreleased, и вы будете удерживать нулевую ссылку (как это было бы в приведенном выше примере stringWithString ). Когда он вам больше не нужен, звоните [foo release].

2 голосов
/ 06 ноября 2008

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

  • Авто-релиз : в документах говорится, что это вызовет релиз "в какой-то момент в будущем". КОГДА?! По сути, вы можете рассчитывать на то, что объект находится рядом, пока не вернете свой код обратно в цикл системных событий. Система МОЖЕТ освободить объект в любое время после текущего цикла события. (Я думаю, Мэтт сказал это раньше.)

  • Статические строки : NSString *foo = @"bar"; - вы должны сохранить или отпустить это? Нет. Как насчет

    -(void)getBar {
        return @"bar";
    }
    

    ...

    NSString *foo = [self getBar]; // still no need to retain or release
    
  • Правило создания : Если вы создали его, вы являетесь его владельцем и ожидаете его выпуска.

В общем случае, новые программисты Какао путаются, не понимая, какие процедуры возвращают объект с retainCount > 0.

Вот фрагмент из Очень простых правил для управления памятью в какао :

Правила подсчета удержания

  • В пределах данного блока использование -copy, -alloc и -retain должно равняться использованию -release и -autorelease.
  • Объекты, созданные с использованием удобных конструкторов (например, stringWithString NSString), считаются автоматически освобожденными.
  • Реализуйте метод -dealloc для освобождения ваших переменных экземпляра

В первом пуле говорится: если вы позвонили alloc (или new fooCopy), вам нужно вызвать release для этого объекта.

Во 2-м пункте написано: если вы используете вспомогательный конструктор , и вам нужно, чтобы объект висел вокруг (как с изображением, которое будет нарисовано позже), вам нужно сохранить (а затем отпустить) его .

3-й должен быть самоочевидным.

1 голос
/ 16 сентября 2008

Много полезной информации о cocoadev тоже:

0 голосов
/ 06 февраля 2010

Как уже упоминали несколько человек, Apple Введение в управление памятью - безусловно, лучшее место для начала.

Одна полезная ссылка, о которой я еще не упоминал, это Практическое управление памятью . Вы найдете это в середине документов Apple, если вы прочитаете их, но это стоит прямой ссылки. Это блестящее краткое изложение правил управления памятью с примерами и распространенными ошибками (в основном то, что другие ответы здесь пытаются объяснить, но не так хорошо).

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