I have a class which I want to confine to a thread. To be precise I want it's void returning methods to be accessed on a certain thread or serial queue created by the class privately. To acheive this I looked at the NSManagedObjectContext
API as a reference. There is a perform(block:() -> Void)
method which can do this.
This comes with a code pattern that I am a bit uncomfortable. The user of this API needs to make calls to the object in the block of the perform(block:() -> Void)
method. Is there a more elegant solution wherein I can declare that all methods and properties are confined to this particular thread. So essentially the user can access the methods but the internal operation happen on the intended thread.
I know the option where I can go to each method and dispatch work of that method into the intended thread. But this is an additional overhead to write the dispatch code.
Use a property wrapper
@propertyWrapper
struct QueueVariable<T> {
private var _value : T
private let queue : DispatchQueue
var wrappedValue : T {
get {
queue.sync { _value }
}
set {
queue.sync { _value = newValue }
}
}
init(value: T,
queue: DispatchQueue = DispatchQueue(label: "sync queue")) {
_value = value
self.queue = queue
}
}
class Test {
@QueueVariable(value: 100, queue: DispatchQueue(label: "aaa"))
var a1
@QueueVariable(value: "aaa")
var a2
}
Either pass the dispatch queue, or a new one would be generated.
let t1 = Test()
t1.a1 += 5
print(t1.a1)
print(t1.a2)