Confused about @Published safety from Task

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

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

it's quite confusing, then should we add MainActor to every viewmodel which changes ui?

2 Likes