Вопрос проверяет понимание ARC, владения объектами и жизненного цикла при асинхронных операциях.
Объект может быть деаллоцирован, если на него больше нет сильных ссылок. Асинхронный запрос сам по себе не удерживает объект, если в замыкании используется weak self. В этом случае ARC освобождает объект сразу после потери владельца. Запрос продолжает выполняться, но объект уже не существует. Это нормальное поведение системы управления памятью.
Асинхронные операции и жизненный цикл объектов не синхронизированы между собой автоматически.
Определение:
ARC освобождает объект сразу, как только количество сильных ссылок на него становится равно нулю.
Это означает:
ARC не “ждет” завершения сетевого запроса
ARC не знает, что объект логически еще “нужен”
учитываются только сильные ссылки
Если объект удерживался, например, экраном, и экран был закрыт — объект может быть освобожден мгновенно.
Асинхронная операция:
живет своей жизнью
удерживается системой или сервисом
не обязана удерживать вызывающий объект
Если замыкание захватывает self как weak, то оно не увеличивает reference count.
service.load { [weak self] result in
self?.handle(result)
}
Если экран закрыли — self стал nil, и код просто не выполнится.
Многие думают:
“Я же запустил запрос, значит объект должен жить”.
Это неверно.
Жизненный цикл объекта зависит только от сильных ссылок, а не от логики приложения.
Варианты:
хранить запрос и отменять его в deinit
использовать weak self и быть готовым к nil
не рассчитывать на завершение запроса, если объект ушел
Объект может быть деаллоцирован до завершения асинхронного запроса, потому что ARC ориентируется только на сильные ссылки, а не на бизнес-логику. Асинхронный код должен быть написан так, будто объект может исчезнуть в любой момент — это основа безопасной работы с памятью в Swift.