@noescape
can be used like this:
func doIt(code: @noescape () -> ()) {
/* what we CAN */
// just call it
code()
// pass it to another function as another `@noescape` parameter
doItMore(code)
// capture it in another `@noescape` closure
doItMore {
code()
}
/* what we CANNOT do *****
// pass it as a non-`@noescape` parameter
dispatch_async(dispatch_get_main_queue(), code)
// store it
let _code:() -> () = code
// capture it in another non-`@noescape` closure
let __code = { code() }
*/
}
func doItMore(code: @noescape () -> ()) {}
Adding @noescape
guarantees that the closure will not be stored somewhere, used at a later time, or used asynchronously.
From the caller's point of view, there is no need to care about the lifetime of captured variables, as they are used within the called function or not at all. And as a bonus, we can use an implicit self
, saving us from typing self.
.
func doIt(code: @noescape () -> ()) {
code()
}
class Bar {
var i = 0
func some() {
doIt {
println(i)
// ^ we don't need `self.` anymore!
}
}
}
let bar = Bar()
bar.some() // -> outputs 0
Also, from the compiler's point of view (as documented in release notes):
This enables some minor performance optimizations.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…