0

I'm trying to make a thread-safe struct using the @propertyWrapper, but I have such an error from the playground when I'm setting a value. The error goes, only if I change the async to sync, but I just need to have async function

@propertyWrapper
struct SafeThread<Value>{

    private let queue = DispatchQueue(label: "sellQueue",attributes:.concurrent )
    private var value: Value
    
    
    init (wrappedValue: Value){
        self.value = wrappedValue;
    }
    
    
    var wrappedValue :Value {
        get { queue.sync { value } }
        set { queue.async(flags: .barrier) { self.value = newValue } } // there an error 
        
    }
}

And class where I want to use it :

class Safe{
@SafeThread var foo = 0;
    
func threadSafetyExperiment() {
    
    DispatchQueue.global().sync {

        DispatchQueue.concurrentPerform(iterations: 1_000) { _ in
            self.foo += 1
        }
        print(self.foo)
    }
}
}
Andrii Vynnyk
  • 59
  • 1
  • 3
  • @Jessy, no, it doesn't. There is a SWIFT-3 question and it doesn't help me – Andrii Vynnyk Oct 18 '20 at 11:28
  • There is no reason for it not to help you; it's not different enough. You need to develop the skill for that to help you, or else you'll add too much duplication to the internet and it will take up people's time. –  Oct 18 '20 at 13:24

1 Answers1

1

You need to use nonmutating set and for this to have external storage for wrapped value.

Here is possible way. Tested with Xcode 12 / iOS 14.

@propertyWrapper
struct SafeThread<Value>{

    private class Storage {
        var value: Value
        init(initialValue: Value) {
            value = initialValue
        }
    }
    private let queue = DispatchQueue(label: "sellQueue",attributes:.concurrent )
    
    private var storage: Storage
    init (wrappedValue: Value){
        self.storage = Storage(initialValue: wrappedValue);
    }
    
    var wrappedValue :Value {
        get { queue.sync { self.storage.value } }
        nonmutating set { queue.async(flags: .barrier) { self.storage.value = newValue } }
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690