Как отменить долгосрочную задачу в ViewModel?

Это простой тест, но не простой. HomeView показывает TestView в виде листа, TestView скрывает почти все действия (без .task, onReceive...) в TestViewModel, TestViewModel определяет ориентацию устройства и показывает ее в TestView. при отклонении TestView остановите обнаружение.

Работает почти нормально, но при отклонении TestView печать («TestViewModel deinit.») не происходит, и обнаружение все еще работает.

Я думаю, что у Task есть ссылка на TestViewModel, из-за чего TestViewModel не может быть выпущен. Но как исправить?

ОК, следующий вопрос: как отменить задачу в TestViewModel (не в TestView) при отклонении TestView?

Любое предложение?

      struct HomeView: View {
    @State var showTestView = false
    
    var body: some View {
        Button("Show Test View") {
            showTestView = true
        }.sheet(isPresented: $showTestView) {
            TestView()
        }
    }
}

struct TestView: View {
    @StateObject private var vm = TestViewModel()
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        VStack {
            Text("isPortrait = \(vm.isPortrait.description)")
            Button("Dismiss") {
                dismiss()
            }
        }
        .onDisappear {
            print("TestView onDisappear.")
        }
    }
}

@MainActor
class TestViewModel: ObservableObject {
    @Published var isPortrait = false
    
    init() {
        print("TestViewModel init.")
        setup()
    }
    
    deinit {
        print("TestViewModel deinit.")
    }
    
    func setup() {
        Task {
            await observeNotification()
        }
    }
    
    private func observeNotification() async {
        let sequence = NotificationCenter.default.notifications(named: UIDevice.orientationDidChangeNotification)
            .map { _ in await UIDevice.current.orientation }
        for await value in sequence {
            print("orientationDidChangeNotification changed, orientation = \(value).")
            isPortrait = value == .portrait
        }
    }
}

0 ответов

Другие вопросы по тегам