Suppose I have a class whose only state is a reference to a singleton class:
class MyClass {
let networkHelper: NetworkHelper
func makeNetworkRequest(_ url: URL) {
networkHelper.actuallyMakeNetworkRequest(url)
}
}
The NetworkHelper
class is not Sendable
; it maintains some mutable state (although that state is mostly invisible to outside callers). However, the class is a singleton and so any two instances of MyClass
will always hold references to the same NetworkHelper
.
Given that MyClass
contains no mutable state of its own, and that it does hold a reference to a non-Sendable
class instance, does MyClass
conform to Sendable
?
CodePudding user response:
From documentaion
Sendable Classes To satisfy the requirements of the Sendable protocol, a class must:
Be marked final
Contain only stored properties that are immutable and sendable
Have no superclass or have NSObject as the superclass
Classes marked with @MainActor are implicitly sendable, because the main actor coordinates all access to its state. These classes can have stored properties that are mutable and nonsendable.
Classes that don’t meet the requirements above can be marked as @unchecked Sendable, disabling compile-time correctness checks, after you manually verify that they satisfy the Sendable protocol’s semantic requirements.
According to this, to be sendable
- Your MyClass should be final
- Your singleton, networkHelper should be immutable and sendable
- Should have no superclasses [Which already is]
CodePudding user response:
In short, because NetworkHelper
is not Sendable
, MyClass
cannot be Sendable
either. The fact that NetworkHelper
is a singleton is immaterial.
FWIW, the compiler will help you out here: If you attempt to make MyClass
conform to Sendable
(by making it final
and adding Sendable
conformance), the compiler will tell you about the issue with NetworkHelper
not being Sendable
:
final class MyClass: Sendable {
let networkHelper: NetworkHelper = .shared // Stored property 'networkHelper' of 'Sendable'-conforming class 'MyClass' has non-sendable type 'NetworkHelper'
func makeNetworkRequest(_ url: URL) {
networkHelper.actuallyMakeNetworkRequest(url)
}
}
For MyClass
to be Sendable
, you will need to make NetworkHelper
conform to Sendable
, too.
FWIW, if NetworkHelper
has a mutable state, you probably want to make it threadsafe, anyway, and once you do that, making it Sendable
, too, is easy.