У меня есть контроллер представления, который никогда не выпускается после того, как его родительский контроллер представления удаляется из иерархии представлений и освобождается. Каждый его экземпляр в графе памяти выглядит одинаково, поскольку он имеет единственную ссылку на CFNotificationCenter
. Похоже, что другие, не относящиеся к делу, контроллеры представления другого класса имеют одну и ту же ссылку, но все равно освобождаются. Рассматриваемый контроллер представления также не имеет NotificationCenter
наблюдателей, поэтому для меня это не имеет смысла.
Я прикрепил изображение графика памяти с отредактированным истинным именем контроллера представления. Я также уверен, что это полный график контроллера представления, я не выбрал для проверки ни одной ссылки.
Что здесь происходит? Почему его не выпустят?
Вы можете точно увидеть, какой код ссылается на ваш контроллер представления:
Сначала включите Malloc Stack Logging для вашей схемы (откройте редактор схемы с помощью Cmd-Shift-,)
Затем щелкните блок «malloc», указывающий на ваш контроллер представления, и наведите указатель мыши справа от Backtrace, чтобы найти кнопку «Развернуть», чтобы увидеть полную трассировку стека:
Однако наиболее вероятным виновником на самом деле является не уведомление, сохраняющее ваш контроллер представления, поскольку ссылка не является строгой (иначе это была бы жирная стрелка).
Отладчик графа памяти Xcode не показывает, когда объект сохраняет себя. В моем случае это был простой случай сохранения self
в замыкании в моем viewDidLoad
.
Проверка трассировки malloc выявила проблему: сильная ссылка на self
в экранирующем замыкании. CFNotificationCenter
был всего лишь отвлекающим маневром, поэтому он был в основе всех остальных элементов.
У меня тоже есть эта проблема в моем проекте. И я обнаружил, что если я назначу объекту значение nil при вызове CFNotificationCenterAddObserver и CFNotificationCenterRemoveObserver, я все равно смогу получить уведомление — и без проблемы с сохранением при деинициализации объекта, который я ранее добавил в качестве слушателя.
Может быть, повезло больше с инструментами.