【问题标题】:Escaping closure captures mutating 'self' parameter (SWIFT 5) [duplicate]转义闭包捕获变异的“自我”参数(SWIFT 5)[重复]
【发布时间】:2021-02-01 08:46:18
【问题描述】:

我正在尝试使用@propertyWrapper 创建一个线程安全的结构,但是当我设置一个值时,我在操场上遇到了这样的错误。 只有当我将async 更改为sync 时才会出现错误,但我只需要拥有async 功能

@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 
        
    }
}

以及我想使用它的类:

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

        DispatchQueue.concurrentPerform(iterations: 1_000) { _ in
            self.foo += 1
        }
        print(self.foo)
    }
}
}

【问题讨论】:

  • @Jessy,不,它没有。有一个 SWIFT-3 问题,但对我没有帮助
  • 它没有理由不帮你;这还不够不同。你需要培养技能来帮助你,否则你会在互联网上添加太多重复内容,这会占用人们的时间。

标签: swift swift5 swift-playground property-wrapper


【解决方案1】:

您需要使用nonmutating set 并为此拥有用于包装值的外部存储。

这是可能的方法。使用 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 } }
    }
}

【讨论】:

  • 我也有类似的想法,但是这个帖子更好。感谢这篇文章。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多