Метод установки управления памятью Obj-C

Я новичок в Objective-C и скачал код с здесь.
Запустил главу 10, 10.01 CarPartsInit файл проекта xcode.

Одна вещь, о которой мне не ясно, заключается в том, что управление памятью метода установки

- (void) setEngine: (Engine *) newEngine
{
    [newEngine retain] 
    [engine release];
    engine = newEngine;
}

предполагается, что двигатель retainCount будет равен 0 в конце программы.

Я запустил несколько NSLog, и когда программа закончилась... retainCount для двигателя было равно 1... Должен ли он перейти в 0 и освободиться? Или это утечка памяти?


person user372705    schedule 22.06.2010    source источник


Ответы (5)


Вам не следует беспокоиться о сохранении счетчиков. Не стоит даже смотреть на них. Они просто слишком запутаны — на самом деле это частные детали реализации. Показательный пример: счетчик сохранения объектов никогда не обнуляется. Почему? Потому что нет смысла. Объект со счетчиком сохранения, равным 0, будет освобожденным объектом, и отправка сообщений освобожденным объектам является ошибкой (он может сообщить старое значение 1, или он может сообщить что-то совершенно другое, или это может просто привести к сбою вашей программы) . Если вы следуете управлению памятью руководящие принципы и Инструменты не сообщают об утечках, вы должны чувствовать себя хорошо.

person Chuck    schedule 22.06.2010

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

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

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

person Kristopher Johnson    schedule 22.06.2010
comment
что, если это на iPhone, ОС позаботится об этом? так как очень важно избегать автоматического выпуска, а также GC не поддерживается? Будет ли это загружать приложение, если эти воспоминания не будут освобождены? - person user372705; 22.06.2010
comment
Не важно. после завершения программы все ресурсы, связанные с программой, возвращаются. - person bbum; 22.06.2010
comment
@tmlee: ОС освободит память вашего процесса после его завершения. Это справедливо для всех известных мне современных компьютерных платформ, включая iPhone. - person Chuck; 22.06.2010
comment
На самом деле не очень важно избегать авторелиза. Вы можете получить лучшую производительность, если избегаете этого, но если вы не автоматически выпускаете миллионы объектов за раз, это не будет проблемой. - person Kristopher Johnson; 28.06.2010

Все, что экземпляр сохраняет (или выделяет), должно быть освобождено в Dealloc.

-(void) dealloc {
  [engine release]; // no need to set to nil in dealloc
  [super dealloc];
}
person drawnonward    schedule 22.06.2010

Давайте посмотрим, что должен делать setEngine.

  1. кто-то передает новый движок, и вы хотите его использовать. Так что вам нужно "сохранить" его.
  2. у вашей машины, возможно, уже есть двигатель. Так что отпускай. (Обратите внимание, отправка сообщения о выпуске в null ничего не делает)
  3. затем вы присваиваете переданный аргумент "newEngine" свойству автомобиля "engine". Сделанный.

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

person yehnan    schedule 22.06.2010

Пока вы инициализируете свой класс, счетчик памяти движка увеличится на единицу (говоря, что вы инициализируете его).
В вашем установщике новое значение должно быть сохранено, а старое значение освобождено (счетчик сохранения увеличивается с новым значением, затем счетчик уменьшается, чтобы избавиться от старого значения). Таким образом, счетчик удержания по-прежнему равен 1.

При закрытии программы вам также необходимо отпустить Engine в функции Dealloc, чтобы не было утечек памяти.

Отличный способ отслеживать утечки памяти — использовать инструмент "Leaks" в xcode:
run -> Start with Performance Tool -> Leaks.

Другие методы — использование инструмента "Сборка и анализ" для поиска потенциальных утечек памяти:
Сборка > Сборка и анализ.

Надеюсь, я прав, мой объектив-с немного заржавел.

person user373455    schedule 22.06.2010