I am getting this error in a couple of places in my code with Task closure after setting Swift 6 as Language version in XCode.
Passing closure as a 'sending' parameter risks causing data races between code in the current task and concurrent execution of the closure
Below is minimally reproducible sample code.
import Foundation
final class Recorder {
var writer = Writer()
func startRecording() {
Task {
await writer.startRecording()
print("started recording")
}
}
func stopRecording() {
Task {
await writer.stopRecording()
print("stopped recording")
}
}
}
actor Writer {
var isRecording = false
func startRecording() {
isRecording = true
}
func stopRecording() {
isRecording = false
}
}
Compiler's error is not bring too much information about the real error. Consider this line of code await writer.startRecording()
, actually self
is impiled so this code is actually await self.writer.startRecording()
.
Now we can see the error occur because Recorder
is not conform to Sendable
so it can not be capture by closure of Task
.
You can solve your problem by make Recorder
conform to Sendable
.
Another fix is to capture writer
in Task closure
because Actor
is conform to Sendable
by default.
func startRecording() {
Task { [weak writer] in
await writer?.startRecording()
print("started recording")
}
}