Как найти утечку памяти в iOS-приложении без использования Memory Graph Debugger?

«Как найти утечку памяти в iOS-приложении без использования Memory Graph Debugger?» — вопрос из категории Управление памятью, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Основные инструменты — Instruments (Allocations и Leaks) и ручная проверка retain cycles.

1. Инструмент Allocations

Запуск: Product > Profile > Allocations в Xcode.

  • Фильтруйте по именам своих классов.
  • Наблюдайте за ростом счетчика #Persistent или #All.
  • Ищите объекты, которые не освобождаются после ожидаемых событий (например, после dismiss контроллера).
  • Используйте Mark Generation (кнопка внизу) для создания контрольных точек и отслеживания объектов, созданных между ними.

2. Инструмент Leaks

Запуск: Product > Profile > Leaks.

  • Прямо показывает утечки — объекты, на которые больше нет сильных ссылок, но память не освобождена.
  • Часто указывает на проблемы с C-кодом (Core Foundation, необработанные указатели).

3. Ручная проверка retain cycles

  • Проверка вызова deinit:
    class MyViewController: UIViewController {
        deinit {
            print("MyViewController deallocated") // Если не печатается — есть цикл
        }
    }
  • Типичные источники циклов:
    • Замыкания: Всегда используйте [weak self] или [unowned self], когда self удерживает замыкание.
    • Делегаты: Должны быть объявлены как weak.
    • Таймеры: Timer сильно ссылается на target. Используйте блоки или инвалидируйте в deinit.
    • Уведомления (NotificationCenter): Не забывайте удалять наблюдателей.
  • Косвенный анализ: Используйте Debug Memory Graph (кнопка в Xcode) для визуализации графа объектов в конкретный момент времени и поиска неожиданных сильных ссылок.