简体   繁体   中英

SwiftUI @Published and main thread

Could someone explain why I get this warning: Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.

I'm know that if I wrap the changes in DispatchQueue.main.async the problem goes away. Why does it happen with some view modals and not others? I thought that since the variable has @Published it's automatically a publisher on main thread?

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 = []
            }
        }
    }
}

The @Published property wrapper creates a publisher of the declared type, nothing more. The documentation may be able to provide further clarity.

As for it happening on some viewModels and not others, we wouldn't be able to tell here as we don't have the code. However it's always best practice to use DispatchQueue.main.async block or .receive(on: DispatchQueue.main) modifier for combine as you've already figured out when updating your UI.

The chances are your other viewModel is already using the main thread or the properties on the viewModel aren't being used to update the UI, again without the code we'll never be sure.

Evidently, contactsRepo.findMutuals can call its completion handler on a background thread. You need to ward that off by getting back onto the main thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM