I recently read this article here and I have to overthink my current application:
I tried to enable strict concurrency checking and I really get the warning:
Static property 'shared' is not concurrency-safe because it is non-isolated global shared mutable state; this is an error in Swift 6
So okay, I will try to change my code now, but I am not sure, what will be the best solution. The reason, why I use a singleton, is, that I have a client application that requests data from a server. It will be displayed in several SwiftUI-views, so I choosed a @Observable
-class and everytime a function requests new data from the server, this singleton will be updated and all my views too. So far, this works, although I know, that there can be data races. It's getting worse, as sometimes the server pushes new data to the clients, so there is a high chance, that there will be some data races. Therefore I really need to change my code either way.
Using an actor
would be the best solution, but you cannot mark an actor
as @Observable
. The author of the article above suggests to mark the class
as @MainActor
.
First question that I cannot completely answer myself by searching the net: What exactly does @MainActor
? Every article in the net tells, that the code will run on the main actor, on the main queue. The article linked above tells, that making a class @Observable
will make the access serialized and therefore concurrency-safe. So is
@MainActor
@Observable
class MyClass {
...
}
comparable to (what is not yet possible):
@Observable
actor MyActor {
...
}
? What happens for example in this case?
@MainActor
@Observable
class MyClass {
static var shared = MyClass()
var myArray = [1, 2, 3]
}
// somewhere in the code
MyClass.shared.myArray.append(4)
// somewhere else
print(MyClass.shared.myArray.count)
Are these two functions thread serialized and thread safe?
Second question: The author in the above article writes "However, actor isolation might not always work since it complicates access from non-concurrency contexts."
Can anyone explain this further?