Добавить объявление

Захват ссылок в Swift: когда [weak self] становится ловушкой

Всем привет! Наткнулся на интересную статью об отладке памяти в iOS. Автор разбирает реальный кейс, где мелкий UI-баг оказался верхушкой айсберга серьезной проблемы.

С чего все началось:


Пользователи жаловались на странное поведение: при переходе по пуш-уведомлению анимация открытия экрана срабатывала дважды. Казалось бы, мелочь, но именно с таких мелочей часто начинаются интересные расследования.

Расследование по шагам:


Автор методично искал причину. Сначала: классические print-ы по всему стеку вызовов. Оказалось, что обработчик deep link вызывался дважды, и что важнее: от двух разных экземпляров координатора в памяти.

Ключевая зацепка: проблема воспроизводилась только после выхода и повторного входа в аккаунт. Это намекало, что старые объекты не убирались из памяти.

Масштаб проблемы:


Используя Memory Graph Debugger, автор обнаружил шокирующую вещь: в системе оставались жить целые копии части приложения, со всеми координаторами, сервисами и вью-моделями. Каждый перелогин добавлял новый слой в память.

Найденный виновник:


Проблема скрывалась в, казалось бы, корректном коде:

.sink(receiveValue: {
Task { [weak self] in // weak здесь не спасает!
// логика
}
})

Ошибка была в том, что [weak self] стоял во внутреннем замыкании Task, в то время как внешнее замыкание .sink захватывало self сильно по умолчанию.

Решение в одну строку:


Исправление оказалось минимальным, но критически важным:

.sink(receiveValue: { [weak self] in // weak должен быть здесь!
Task {
// логика
}
})

Вывод:


Эта история наглядно показывает, как механическая, но невнимательная расстановка [weak self] может создать иллюзию безопасности, скрывая реальную утечку памяти. Мы часто действуем по шаблону, добавляя слабый захват в асинхронные блоки, забывая, что корень проблемы может находиться уровнем выше - в замыкании, которое инициирует эту асинхронную операцию. Ключевой урок здесь в том, что борьба с retain cycles требует не ритуала, а понимания полного контекста захвата, особенно при работе с цепочками и вложенными замыканиями.
28.12.2025 58 545