beingadrian beingadrian - 2 months ago 35
Swift Question

Why do closures require an explicit `self` when they're all non-escaping by default in Swift 3?

I've noticed that in Swift 2.2, closures marked as non-escaping with

@noescape
do not require an explicit
self
. In Swift 3, all closures are non-escaping by default and now requires them to be marked with
@escaping
if you want them be able to escape.

Given that all of the closures in Swift 3 by default are non-escaping, why do they require an explicit
self
?

final class SomeViewController: NSViewController {

var someClosure: () -> () = { _ in }

override func viewDidLoad() {
super.viewDidLoad()

someClosure = {
view.layer = CALayer() // ERROR: Implicit use of `self` in closure; use `self.` to make capture semantics explicit
}
}
}

Answer

Stored closures are considered escaping by default, even when they aren't really. There's no way to mark them non-escaping so we're stuck like this until they add @noescape back to the language, which they may or may not do. See this discussion on the swift-evolution mailing list.