После guard let self задача сильно удерживает ViewModel через await. Поэтому [weak self] в capture list не гарантирует deinit при уходе назад.
final class ProfileViewModel1 {
После 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 должен поддерживать отмену.