In the following example, the private _valuePublisher has been exposed as a type-erased Publisher through a nonisolated property. Additionally, the current value of the _valuePublisher is also exposed as a nonisolated property. The compiler is happy with this arrangement but I'm not sure about the thread-safety aspect of this especially for the unwrappedValue property. Any thoughts?
final actor MyActor {
private let _valuePublisher = CurrentValueSubject<Int, Never>(0)
nonisolated var valuePublisher: AnyPublisher<Int, Never> {
_valuePublisher.eraseToAnyPublisher()
}
nonisolated var unwrappedValue: Int {
_valuePublisher.value
}
func updateValue(_ value: Int) {
_valuePublisher.send(value)
}
}
You asked:
Technically, this actor has no mutable state and thus presents no thread-safety risk; the risk rests in the referenced
CurrentValueSubject.However, if you give the actor a mutable state (by making the actor’s property a
varinstead oflet) and try to expose that via a non-isolated property, that results in errors, as that would threaten the thread-safety of the actor, itself:E.g.:
In short, in the original code snippet, the actor’s property was immutable, so the potential risk rests in the thread-safety of the referenced class, not in that of the actor.
That having been said, there is a thread-safety issue here.
To have the compiler perform more robust checks, I would advise changing the “Strict Concurrency Checking” setting to “Complete”:
When you do this, it will warn you of the problems:
E.g.: