Created
September 18, 2024 18:37
-
-
Save robertmryan/a9c3dc36d9557f9396baefbc876c9b9b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
final class ComplexData: @unchecked Sendable { | |
private let lock = NSLock() | |
private var _name: String | |
var name: String { | |
get { lock.withLock { _name } } | |
set { lock.withLock { _name = newValue } } | |
} | |
init(name: String) { | |
_name = name | |
} | |
} |
By the way, if you're worried about how hairy ComplexData
might get with lots and lots of properties, you can abstract this synchronization logic out into a property wrapper:
@propertyWrapper
struct Synchronized<T>: @unchecked Sendable {
private var _wrappedValue: T
private let lock = NSLock()
var wrappedValue: T {
get { lock.withLock { _wrappedValue } }
set { lock.withLock { _wrappedValue = newValue } }
}
init(wrappedValue: T) {
_wrappedValue = wrappedValue
}
}
final class ComplexData: @unchecked Sendable {
@Synchronized var firstName: String
@Synchronized var lastName: String
init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As an aside, this pattern only works if the properties are not reference types with their own mutable properties. We’re OK with
String
, but if you add more properties, be wary of this limitation.