I keep getting a runtime error:
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.
This occurs when I’m setting my @Published array = to a new value. That setting of the array occurs within a .receive(on: DispatchQueue.main).sink block.
Example code:
class MyClass: ObservableObject {
@Published var movies: [Movie] = []
var retrievePublisher: AnyCancellable?
func retrieve() async throws {
retrievePublisher = (await retrieveMovies()).receive(on: DispatchQueue.main).sink(receiveCompletion: { _ in
}, receiveValue: { [weak self] newArray in
guard let self else { return }
movies = newArray.result
})
}
}
func retrieveMovies() async -> AnyPublisher<RetrieveResult<Movie>, CustomError> {
// ...
}
However, if I tag the class with @MainActor, the runtime error does not occur anymore.
Additionally, if I set a breakpoint on that movies variable or where I’m setting it, I can observe that everything is indeed occurring on the main thread.
Why is @MainActor necessary in this case? What about .receive(on: DispatchQueue.main) is causing the error: Publishing changes from background threads is not allowed?




