Swift Nested Closure Captures
There is no escape
Update: This has been fixed!
Just in case others run into this issue, I wanted to document it here. @noescape
causes some curious behavior when nesting closures. It appears to cause a captured mutable local to become a separate copy, meaning changes that should be visible in one sibling closure aren't visible to the other.
import Cocoa
func outerExecute(@noescape f: ()->Void) {
f()
}
func innerExecute(f1: ()->Void, f2: ()->Void) {
f1()
f2()
}
func crashCity() -> NSString? {
var local: NSString?
outerExecute {
innerExecute({ local = "Cool Beans" },
{
println("\(local!)")
})
}
return local
}
crashCity()
If you remove @noescape
this code prints "Cool Beans" as expected. If that attribute is present the second closure will crash with an unexpected nil
.
Radar #20657776 filed. In the mean time you can just avoid @noescape
This blog represents my own personal opinion and is not endorsed by my employer.