Under Swift, the typical paradigm of try-catch-finally
has been replaced with do-defer-catch
, where defer
plays the role of finally
, ensuring code is executed regardless of the error handling path.
It seems that in an asynchronous environment within Swift Concurrency, this paradigm may break down:
struct SandView: View {
@State private var progress: Progress?
var body: some View {
Button("Sand Box") {
Task {
do {
self.progress = .init()
defer { self.progress = nil } // property 'progress' isolated to global actor 'MainActor' can not be mutated from a non-isolated context
try await withCheckedThrowingContinuation { $0.resume() }
} catch {
print("uh oh: \(error)")
}
}
}
}
}
Is there a solution to this or an alternative paradigm that can be recommended?