func main2() {
studentResult(rollNo: "1234", onResultFetched: { isPassed in
print(isPassed ? "You are pass" : "You are fail")
})
}
We use @escaping
when we want to wait for the something so it tells the function to wait and won’t destroy itself until we get response
func studentResult(rollNo: String, onResultFetched: @escaping (Bool) -> Void) {
print("Fetching result for Roll Number: (rollNo)")
// Here we are waiting 5 seconds for the repsonse
DispatchQueue.main.asyncAfter(deadline: .now()+5) {
onResultFetched(true) // Error "Sending 'onResultFetched' risks causing data races"
}
}
main2()
I made a closure in swift and its giving me this error “Sending ‘onResultFetched’ risks causing data races”
I try the closure and its giving me the error of risk causing data races but before I do the same it works well here it will giving me the error
M.Hasnain Bangash is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
You are likely building under Swift 6 mode, in which case you will generally want to add @MainActor
in front of the @escaping
to require that the closure be something that can run on the main actor, and then dispatch to the main actor like this:
func studentResult(rollNo: String, onResultFetched: @MainActor @escaping (Bool) -> Void) {
print("Fetching result for Roll Number: (rollNo)")
// Here we are waiting 5 seconds for the repsonse
Task { @MainActor in
try await Task.sleep(for: .seconds(5))
onResultFetched(true)
}
}
But to regain the old behavior, you can switch back to Swift 5 mode, which is the default for new projects, but not for packages. In Xcode, see the project build settings, and set “Swift Language Version” to “Swift 5.” This should remove the error.
Not related to your question, but the modern way to write this would look more like this:
@MainActor func main2() async {
async let isPassed = studentResult(rollNo: "1234")
print(await isPassed ? "You are pass" : "You are fail")
}
func studentResult(rollNo: String) async -> Bool {
print("Fetching result for Roll Number: (rollNo)")
// Here we are waiting 5 seconds for the response
try? await Task.sleep(for: .seconds(5))
return true
}
await main2()
This is appropriate for both Swift 5 and Swift 6.
0