final class ProfileViewModel1 {

После guard let self задача сильно удерживает ViewModel через await. Поэтому [weak self] в capture list не гарантирует deinit при уходе назад.

Короткий ответ

Что ответить на собеседовании

После guard let self задача сильно удерживает ViewModel через await. Поэтому [weak self] в capture list не гарантирует deinit при уходе назад.

Подробный разбор

Ответ с пояснениями

Условие

final class ProfileViewModel1 { enum State { ... }

var state: State = .idle
let service: UserService

init(service: UserService) { ... }

func onBackPress() {
    // view deinit
}

func loadUser() {
    state = .loading

    Task { [weak self]
        guard let self else { return }
        do {
            let user = try await self.service.fetchUser()
            self.state = .loaded(user)
        } catch {
            self.state = .failed(error.localizedDescription)
        }
    }
}

}

Ответ

После guard let self задача сильно удерживает ViewModel через await. Поэтому [weak self] в capture list не гарантирует deinit при уходе назад.

В примере ViewModel не хранит Task, поэтому это не обязательно цикл self → task → self: выполняемая задача сама удерживает объект до завершения. onBackPress ничего не отменяет.

UI-состояние изолируйте MainActor. Храните handle задачи для явной отмены при уходе или новом запросе, а сервис захватите отдельно до Task; self можно использовать слабо только после await. Отмену не показывайте как обычную ошибку, а поздний результат старого запроса защищайте идентификатором операции. Сам cancel лишь помечает задачу: fetchUser должен поддерживать отмену.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее