Here is the code causing crash:
import Foundation
let KEY = "key"
func doHeavyWork() {
print("Enter doHeavyWork")
defer { print("Leave doHeavyWork") }
defer {
let callback: () -> () = {
let existed = dict.keys.contains(KEY)
print("In callback: \(existed)")
}
callback()
}
let dict: [String: Int] = [
KEY: 0
]
print("Do something")
}
doHeavyWork()
Thread.sleep(forTimeInterval: 3)
The version of swift is:
swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0
If I move the declaration of dict
to be earlier than the second defer-statement, it doesn't crash.
According to some try-and-error, I believe the crash is due to:
- the variable,
dict
, is destroyed first - then the closure,
callback
, is called and it access the variable,dict
However, it's promised that the closure can access variables even if the scope is no longer existed.
I believe it is a syntax bug since the following codes got compile error
error: use of local variable 'dict' before its declaration
defer {
let existed = dict.keys.contains(KEY)
print("In callback: \(existed)")
}
let dict: [String: Int] = [
KEY: 0
]
and
let callback: () -> () = {
let existed = dict.keys.contains(KEY)
print("In callback: \(existed)")
}
let dict: [String: Int] = [
KEY: 0
]
callback()
But it doesn't cause a compile error when using defer+closure.