Modifying struct instance variables within a Dispatch closure in Swift
我正在使用Swift的
Closure cannot implicitly capture a mutating self parameter
为了更好地解释,这是一个简单的示例:
1 2 3 4 5 6 7 8 9 10 11 12 | public struct ExampleStruct { let connectQueue = dispatch_queue_create("connectQueue", nil) var test = 10 mutating func example() { if let connectQueue = self.connectQueue { dispatch_sync(connectQueue) { self.test = 20 // error happens here } } } } |
这些Swift二进制文件中的某些内容现在必须更改,这导致我之前的工作代码损坏。 我要避免的一种解决方法是将struct设置为类,这确实有助于解决问题。 让我知道是否还有其他方法。
我无法测试它,因为我没有使用带有该错误的构建,但是我很确定通过显式捕获自身可以解决此问题:
1 2 3 | dispatch_sync(connectQueue) { [self] in self.test = 20 } |
编辑:显然它不起作用,也许您可以尝试一下(不是很好tbh):
1 2 3 4 5 | var copy = self dispatch_sync(connectQueue) { copy.test = 20 } self = copy |
如果您想详细了解原因,请参阅负责任的Swift提案。
新的分派API使得
1 2 3 | connectQueue.sync { test = 20 } |
您正在使用Swift3,因为您提到了最近的
1 2 3 4 5 6 7 8 9 10 11 | public struct ExampleStruct { let connectQueue = DispatchQueue(label:"connectQueue", attributes: .concurrent)//This creates a concurrent Queue var test = 10 mutating func example() { connectQueue.sync { self.test = 20 } } } |
如果您对其他类型的队列感兴趣,请检查以下内容:
1 2 3 4 | let serialQueue = DispatchQueue(label:"YOUR_QUEUE", attributes: .serial) serialQueue.sync { // } |
异步和异步获取
1 2 3 4 5 6 | DispatchQueue.main.async { //async operations } DispatchQueue.main.sync { //sync operations } |
如果您对背景感兴趣:
1 2 3 | DispatchQueue.global(attributes: .qosDefault).async { //async operations } |
您可以参考Swift3中的新功能以及对现有版本的更改:从Swift 2.2迁移到Swift 2.3或Swift 3