Как определить сильные ссылочные циклы в Swift?
Есть ли инструмент или метод для поиска сильных циклов ссылок в моем SWIFT-коде?
Сильный ссылочный цикл - это когда два экземпляра классов ссылаются друг на друга без надлежащих мер безопасности (weak
/unowned
), поэтому не позволяют сборщику мусора избавиться от них, как только все созданные мной переменные перестанут ссылаться на эти объекты.
Ответы
Ответ 1
Вы можете добавлять функции deinit в свои классы, которые будут вызываться, когда ваши объекты будут освобождены.
Если deinit не вызывается, пока приложение работает, вы можете нажать кнопку Graph Debug Memory Graph (обведенный ниже) и проверить, что имеет отношение к чему.
![Кнопка графика отладки памяти]()
Используйте раскрывающиеся меню в верхней части средней панели для переключения между классами и экземплярами классов.
Если что-то получает выделение снова и снова без освобождения, вы должны увидеть несколько экземпляров, и вы сможете увидеть через наклонный график, если один из его дочерних элементов имеет сильную ссылку на его родителя.
Ответ 2
Метод поиска сильных эталонных циклов в Swift аналогичен методу Objective-C.
Вы запускаете приложение из Xcode, выполняете приложение достаточно, чтобы манифестировать цикл, а затем нажмите на кнопку "график отладочной памяти" (< img src= "https://i.stack.imgur.com/QC48M.png" alt= "график отладки памяти" > ). Затем вы можете выбрать неизданный объект на панели слева, и он покажет вам график памяти, который часто может иметь четкие ссылочные циклы:
![график отладки памяти]()
Иногда циклы памяти не столь очевидны, как это, но вы можете хотя бы увидеть, какой объект поддерживает сильную ссылку на рассматриваемый объект. В случае необходимости вы можете отследить назад и определить, что следует держать в силе, и т.д.
Иногда зная, какой объект хранит сильную ссылку, недостаточно, и вы действительно хотите знать, где в вашем коде была установлена сильная ссылка. Опция "malloc stack", как показано в fooobar.com/questions/33524/..., может использоваться для определения того, что было в стеке вызовов, когда эта сильная ссылка была установлена (часто позволяя вам идентифицировать точную строку кода, где эти сильные ссылки были установлены). Для получения дополнительной информации см. Видео WWDC 2016 Visual Debugging с Xcode.
Вы также можете использовать Инструменты для идентификации просочившегося объекта. Просто запустите приложение с помощью инструментов с помощью инструмента "Разделения" несколько раз (не один или два раза), возвращая приложение обратно в какое-то состояние стабильного состояния, и если память продолжает расти, тогда у вас, вероятно, будет сильный ссылочный цикл. Вы можете использовать инструмент "Выделения" для определения того, какие объекты не выпускаются, использовать функцию "отсчет количества записей", чтобы точно определить, где были установлены эти сильные ссылки, и т.д.
См. видео WWDC 2013 Устранение проблем с памятью и видео WWDC 2012 Производительность приложений iOS: память для ознакомления с проблемами идентификации и устранения проблем с памятью. Основные предлагаемые там технологии по-прежнему применимы сегодня (хотя инструменты пользовательского интерфейса инструментов немного изменились... если вы хотите ознакомиться с немного измененным пользовательским интерфейсом, см. Видео WWDC 2014 Улучшение вашего приложения с помощью инструментов).
В стороне, "сбор мусора" относится к совершенно другой системе памяти и здесь не применим.
Ответ 3
Используйте инструменты для проверки утечек и потери памяти. Используйте Mark Generation (Heapshot) в инструменте Allocations на инструментах.
Для того, чтобы использовать Heapshot для поиска памяти, см. блог bbum
В основном метод состоит в том, чтобы запускать инструменты, выделять инструмент, делать снимок, запускать итерацию вашего кода и повторять еще один кучей, повторяя 3 или 4 раза. Это будет указывать на память, которая выделяется и не выдается во время итераций.
Чтобы выяснить, какие результаты раскрываются, чтобы увидеть отдельные распределения.
Если вам нужно посмотреть, где сохраняются, выпускаются и автореализовываются для инструментов использования объекта:
Запуск в инструментах, в поле "Абонирование" задано значение "Запись отсчетов" (для Xcode 5 и ниже вы должны остановить запись, чтобы установить параметр). Причина, по которой приложение запускается, останавливает запись, разворачивается, и вы сможете увидеть, где все сохраняется, выпуски и автореализаторы.
![]()
Ответ 4
очень простой подход заключается в том, чтобы поместить печать в deinitialiser
deinit {
print("<yourviewcontroller> destroyed.")
}
убедитесь, что вы видите, что эта строка печатается на консоли. поместите deinit во все ваши контроллеры view. в случае, если вы не смогли увидеть конкретный диспетчер view, это означает, что они являются ссылочным циклом. Возможные причины: делегирование является сильным, замыкания, фиксирующие self, таймеры, которые не являются invaidated, и т.д.
Ответ 5
Вы можете использовать Инструменты для этого. В последнем абзаце в этой статье говорится:
Как только инструменты откроются, вы должны запустить свое приложение и выполнить некоторые взаимодействия, особенно в областях или контроллерах просмотра, которые вы хотите протестировать. Любая обнаруженная утечка будет отображаться как красная линия в разделе "Утечки". В представлении помощника есть область, в которой инструменты покажут вам трассировку стека, связанную с утечкой, давая вам информацию о том, где может быть проблема, и даже позволяя вам перейти непосредственно к нарушившемуся коду.