在 Swift 的 Dispatch 闭包中修改结构实例变量
Modifying struct instance variables within a Dispatch closure in Swift
我正在使用 Swift 的 DEVELOPMENT-SNAPSHOT-2016-06-06-a
版本。我似乎无法解决这个问题,我已经尝试在不同的地方使用 @noescape
,但我仍然有以下错误:
Closure cannot implicitly capture a mutating self parameter
为了更好地解释,这里有一个简单的例子:
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 二进制文件中一定发生了某些更改,现在导致我以前工作的代码中断。我想避免的一种解决方法是使我的结构成为 class,这确实有助于解决问题。让我知道是否有其他方法。
自从您提到 Swift
最近的 dev snapshot
以来,您正在使用 Swift3。试试下面,让我知道它是否有效:
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
}
}
}
如果您对其他类型的队列感兴趣,请检查这些:
let serialQueue = DispatchQueue(label: "YOUR_QUEUE", attributes: .serial)
serialQueue.sync {
//
}
异步和同步获取mainQueue
:
DispatchQueue.main.async {
//async operations
}
DispatchQueue.main.sync {
//sync operations
}
如果您对背景感兴趣:
DispatchQueue.global(attributes: .qosDefault).async {
//async operations
}
关于 Swift3 中的新功能和对现有版本的更改,您可以参考这篇文章:Migrating to Swift 2.3 or Swift 3 from Swift 2.2
我无法测试它,因为我没有使用带有该错误的构建,但我很确定通过捕获自我显式你可以修复它:
dispatch_sync(connectQueue) { [self] in
self.test = 20
}
编辑:显然它不起作用,也许你可以试试这个(不是很好 tbh):
var copy = self
dispatch_sync(connectQueue) {
copy.test = 20
}
self = copy
如果您想了解更多原因,here is the responsible Swift proposal。
新的调度 API 使 sync
方法 @noreturn
所以你不需要显式捕获:
connectQueue.sync {
test = 20
}
我正在使用 Swift 的 DEVELOPMENT-SNAPSHOT-2016-06-06-a
版本。我似乎无法解决这个问题,我已经尝试在不同的地方使用 @noescape
,但我仍然有以下错误:
Closure cannot implicitly capture a mutating self parameter
为了更好地解释,这里有一个简单的例子:
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 二进制文件中一定发生了某些更改,现在导致我以前工作的代码中断。我想避免的一种解决方法是使我的结构成为 class,这确实有助于解决问题。让我知道是否有其他方法。
自从您提到 Swift
最近的 dev snapshot
以来,您正在使用 Swift3。试试下面,让我知道它是否有效:
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
}
}
}
如果您对其他类型的队列感兴趣,请检查这些:
let serialQueue = DispatchQueue(label: "YOUR_QUEUE", attributes: .serial)
serialQueue.sync {
//
}
异步和同步获取mainQueue
:
DispatchQueue.main.async {
//async operations
}
DispatchQueue.main.sync {
//sync operations
}
如果您对背景感兴趣:
DispatchQueue.global(attributes: .qosDefault).async {
//async operations
}
关于 Swift3 中的新功能和对现有版本的更改,您可以参考这篇文章:Migrating to Swift 2.3 or Swift 3 from Swift 2.2
我无法测试它,因为我没有使用带有该错误的构建,但我很确定通过捕获自我显式你可以修复它:
dispatch_sync(connectQueue) { [self] in
self.test = 20
}
编辑:显然它不起作用,也许你可以试试这个(不是很好 tbh):
var copy = self
dispatch_sync(connectQueue) {
copy.test = 20
}
self = copy
如果您想了解更多原因,here is the responsible Swift proposal。
新的调度 API 使 sync
方法 @noreturn
所以你不需要显式捕获:
connectQueue.sync {
test = 20
}