How can I call defer inside the Task modifier in Swift? I want to perform clean up operations in defer. This includes setting loadingState to .idle and selectedImage to nil etc. The defer code should fire whether the exception is thrown or not.
Task {
do {
defer {
print("DEFER")
self.selectedImage = nil
loadingState = .idle
chatText = ""
}
try await sendMessage()
print("")
} catch {
print(error.localizedDescription)
}
}
But I get the following compilation error:
Main actor-isolated property 'loadingState' can not be mutated from the main actor
Any help is appreciated.
UPDATE:
Task { @MainActor in
do {
defer {
print("DEFER")
loadingState = .idle
self.selectedImage = nil
loadingState = .idle
chatText = ""
}
try await sendMessage()
} catch {
print(error.localizedDescription)
}
}
UPDATE 2
Here is minimal code that produces a similar error:
enum SampleError: Error {
case operationFailed
}
func doSomething() {
var age = 40
Task {
do {
defer {
age = 50
}
throw SampleError.operationFailed
} catch {
print(error)
}
}
}
doSomething()
This was a known bug that has since been fixed in the Swift compiler. It is resolved in Swift 5.8+ via this patch to the Swift compiler.
This enables the following (simplified) code example to compile correctly.
// Compiles on Swift 5.8+
@MainActor
class Tester {
var x = 0
func run() {
Task {
defer { x += 1 }
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With