Число сохраняемых объектов никогда не опускается ниже 1, несмотря на преднамеренное превышение

Я проверяю количество оставшихся объектов

NSLog(@"r = %d", [aObject retainCount];

Кажется, что самое низкое значение, которое я могу получить, это "r = 1", даже если я намеренно добавляю дополнительные вызовы "release"

[aObject release];

Ограничение "r = 1" сохраняется, даже если я пытаюсь поместить тестовые коды "release" и "NSLog" в объект dealloc метод.

Кажется, что во время выполнения Cocoa мои дополнительные выпуски игнорировались вплоть до "r = 1" перед тем, как завершиться с "EXC_BAD_ACCESS" в самом конце примера программы (без GC).

Мое единственное объяснение (предположение) состоит в том, что нам нужен r >= 1 для доступа к объекту. И во время выполнения Какао просто пытается удержать счет сохранения любого объекта от преждевременного достижения нуля.

Может ли кто-нибудь подтвердить или исправить меня, если я ошибаюсь?

6 ответов

Решение

Когда количество сохраняемых объектов приближается к 0 (т. Е. Число сохраняемых единиц равно 1, и освобождение было вызвано снова), он освобождается вместо того, чтобы потрудиться сделать окончательный декремент.

Как я узнал от bbum (и других), не используйте retainCount, Он не предназначен для того, чтобы быть информативным в отношении сохранения состояния объекта. Просто прочитайте Руководство по программированию управления памятью и не отклоняйтесь от его практики. Не пытайтесь использовать retainCount для управления вашей памятью.

См. Сколько раз я освобождаю выделенный или сохраненный объект?,

Когда использовать -retainCount?,

и т.п.

Если retainCount когда-либо == 0, особенность достигнута!

Курица встретить яйцо. Или это куриное яйцо.

По определению, освобождение объекта с одним оставшимся удержанием означает, что объект освобожден. Любые последующие вызовы методов приведут к неопределенному поведению.

Инструмент Instruments обеспечивает обнаружение зомби, что более эффективно, чем попытка отладки подсчета ссылок Cocoa самостоятельно. Используйте команду Xcode Run > Run with Performance Tool > Zombies. Он определяет, когда вы вызываете метод для освобожденного объекта, и показывает историю сохранения / выпуска для полного жизненного цикла объекта. Жизнь намного лучше, так как Apple добавила этот инструмент.

Философия управления памятью, основанная на подсчете ссылок, заключается в том, что объект существует, пока на него ссылаются>=1 раз. retainCount = 0 теоретически означает, что на объект больше не ссылаются, поэтому вы не можете получить [aObject retainCount] == 0; потому что, если вы все еще можете передавать сообщения, объект существует и остается на aObject, таким образом, имеет по крайней мере retainCount=1.

Когда ссылка на объект становится равной 0, этот объект становится "объектом-зомби", но вы все равно можете отправить ему сообщение retainCount, потому что Xcode по умолчанию не "Включал объекты-зомби" в управлении памятью, что означает, что Xcode не проверял объекты-зомби,

Если вы заставите Xcode проверять объекты-зомби, отметив галочкой "Включить объекты-зомби" в "Редактировать схему-> Выполнить-> Диагностика-> Включить объекты-зомби", вы получите сообщение об ошибке, когда продолжите отправку сообщения объекту после того, как его ссылка станет 0.

Снимок:

Другие вопросы по тегам