I'm using the DEVELOPMENT-SNAPSHOT-2016-06-06-a
version of Swift. I cannot seem to get around this issue, I've tried using @noescape
in various places, but I still have the following error:
Closure cannot implicitly capture a mutating self parameter
To better explain, here is a simple example:
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
}
}
}
}
Something must have changed in these Swift binaries that is now causing my previously working code to break. A workaround I want to avoid is making my struct a class, which does help in fixing the issue. Let me know if there is another way.
I cannot test it, because I'm not using a build with that error, but I'm pretty sure by capturing self explicitly you can fix it:
dispatch_sync(connectQueue) { [self] in
self.test = 20
}
EDIT: Apparently it doesn't work, maybe you can try this (not very nice tbh):
var copy = self
dispatch_sync(connectQueue) {
copy.test = 20
}
self = copy
If you want to read more on why, here is the responsible Swift proposal.
The new dispatch API makes the sync
method @noreturn
so you wouldn't need the explicit capture:
connectQueue.sync {
test = 20
}
You are using Swift3 since you mentioned a recent dev snapshot
of Swift
. Try below and let me know if it works:
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
}
}
}
If you are interested in other types of queues, check these:
let serialQueue = DispatchQueue(label: "YOUR_QUEUE", attributes: .serial)
serialQueue.sync {
//
}
Get the mainQueue
asynchronously and synchronously:
DispatchQueue.main.async {
//async operations
}
DispatchQueue.main.sync {
//sync operations
}
And if you are interested in Background:
DispatchQueue.global(attributes: .qosDefault).async {
//async operations
}
You could refer this for new features in Swift3 and for changes to existing version: Migrating to Swift 2.3 or Swift 3 from Swift 2.2