So I have a class that inherits from ObservableObject, with an @Published variable. I thought from my readings that @Published was implicitly "main actor" these days, so that it would be safe to set the variable from inside a Task where execution is not on the main thread. But doing so seems to have resulted in a deadlock?
(The main thread is calling self.objectWillChange.send(), and is stuck in _os_unfair_lock_lock_slow, which has called __ulock_wait).
The Task, which is setting the @Published variable, is calling ObservableObjectPublisher.send(), and then blocked trying to get _MovableLockLock (in SwiftUI) which bottoms out at a __psync_mutexwait.
Is this my bug for setting the @Published variable from a task or a swift UI bug?
1 Like
so @Published itself is thread safe... but... changes posted to SwiftUI must be done on the main actor. So in reality you should mark your ObservableObject as @MainActor.
5 Likes
swhitty
(Simon Whitty)
3
So it makes sense for it's publisher to be Sendable and pass it across actor boundaries:
extension Published.Publisher: @unchecked Sendable where Output: Sendable { }
1 Like
PineLover
(PineLover)
4
it's quite confusing, then should we add MainActor to every viewmodel which changes ui?
2 Likes