TAGS :Viewed: 7 - Published at: a few seconds ago

[ Escaping Closures in Swift ]

I'm new to Swift and I was reading the manual when I came across escaping closures. I didn't get the manual's description at all. Could someone please explain to me what escaping closures are in Swift in simple terms. Thank you so much.

Answer 1


Consider this class:

class A {
    var closure: (() -> Void)?
    func someMethod(closure: () -> Void) {
        self.closure = closure
    }
}

someMethod assigns the closure passed in, to a property in the class.

Now here comes another class:

class B {
    var number = 0
    var a: A = A()
    func anotherMethod() {
        a.someMethod { self.number = 10 }
    }
}

If I call anotherMethod, the closure { self.number = 10 } will be stored in the instance of A. Since self is captured in the closure, the instance of A will also hold a strong reference to it.

That's basically an example of an escaped closure!

You are probably wondering, "what? So where did the closure escaped from, and to?"

The closure escapes from the scope of the method, to the scope of the class. And it can be called later, even on another thread! This could cause problems if not handled properly.

To avoid accidentally escaping closures and causing retain cycles and other problems, use the @noescape attribute:

class A {
    var closure: (() -> Void)?
    func someMethod(@noescape closure: () -> Void) {
    }
}

Now if you try to write self.closure = closure, it doesn't compile!

Update:

In Swift 3, all closure parameters cannot escape by default. You must add the @escaping attribute in order to make the closure be able to escape from the current scope. This adds a lot more safety to your code!