主要演员是否被隔离?

问题描述 投票:0回答:1

我有以下视图模型

@MainActor
final class SomeViewModel {
    func loadFromService() async {
        do { 
             let dto = try await networkService.theServiceIneedHere()
            //process dto
            //state is a @Published property and observed by a SwiftUI view to update the UI.
            state = .success(viewData)
            }catch {
                state = .failure(someError)
            }
    }
}

我的问题是,如果从我的 SwiftUI 视图任务方法调用 loadFromService 并且我的 SwiftUI 视图未标记为“@MainActor”,那么 loadFromService() 是否在 MainActor 线程上运行?即它不是孤立的?

以下是上述代码的更好方法吗?

final class SomeViewModel {
    func loadFromService() async {
            do {
               let dto = try await networkService.theServiceIneedHere()
                await handleServiceSuccess(with:dto)
             } catch {
                await MainActor.run {
                    state = .failure(someError)
                    }
                }
       }
}

@MainActor
private func handleServiceSuccess(with: DTO) {
    //process dto, update state here
    state = .success(viewData)
}

在第二种方法中,我觉得loadFromService与主线程分离,只有当我们需要更新UI时,我们才切换回主线程。

ios swift swiftui async-await swift-concurrency
1个回答
0
投票

第一种方法是我的首选方法。因为这样你就不需要在更新任何 UI 参数(很可能是 @Published 属性)之前切换到主线程。

我还不熟悉新的

@Observable
,但这至少是我对
@ObservableObject
的建议,因为您将属性存储为
@Published
并在视图模型中更新它们。


如果你的

networkService.theServiceIneedHere()
没有标记为@MainActor,那么它不会被强制在主线程上。

try await callToAsync()
不继承调用 actor。

因此,在第一个示例中,您的网络调用在任何线程上完成,并且状态在主线程上更新。

SwiftUI View body getter 已在其协议中标记为 MainActor。因此,即使您使用

Task {}
,您体内的每个代码块也会在主线程上执行,因为
Task
继承了调用 actor。

© www.soinside.com 2019 - 2024. All rights reserved.