SwiftUI @Published 和主线程

SwiftUI @Published and main thread

有人可以解释为什么我会收到此警告:不允许从后台线程发布更改;确保在模型更新时从主线程发布值(通过像 receive(on:) 这样的操作符)。

我知道,如果我将更改包装在 DispatchQueue.main.async 中,问题就会消失。为什么它会发生在某些视图模态而不是其他视图模态上?我认为由于变量具有 @Published 它会自动成为主线程上的发布者?

class VM: ObservableObject {
    
    private let contactsRepo = ContactsCollection()
    
    @Published var mutuals: [String]?
    
    func fetch() {
        contactsRepo.findMutuals(uid: uid, otherUid: other_uid, limit: 4) { [weak self] mutuals in
            guard let self = self else { return }
            if mutuals != nil {
                self.mutualsWithHost = mutuals // warning...
            } else {
                self.mutualsWithHost = []
            }
        }
    }
}

@Published 属性 包装器创建一个声明类型的发布者,仅此而已。 documentation 或许能够提供进一步的清晰度。

至于它发生在某些 viewModel 上而不发生在其他 viewModel 上,我们无法在此处说明,因为我们没有代码。然而,最好的做法是使用 DispatchQueue.main.async 块或 .receive(on: DispatchQueue.main) 修饰符进行合并,正如您在更新 UI.

时已经知道的那样

很有可能您的其他 viewModel 已经在使用主线程,或者 viewModel 上的属性未被用于更新 UI,同样,如果没有代码,我们将永远无法确定。

显然,contactsRepo.findMutuals 可以在后台线程上调用其完成处理程序。您需要通过回到主线程来避免这种情况。