How are escaping closures implemented in Swift 3 (under the hood)? Are they implicitly block_copied/retained like in objective-c?

后端 未结 1 343
野性不改
野性不改 2020-12-16 06:47

I am trying to understand how escaping closures work in Swift 3? Coming from the Objective-C world, for scenarios where the closure could escape the return of its enclosing

相关标签:
1条回答
  • 2020-12-16 07:02

    It is true that closures are implicitly retained (strongly) when you save them as properties or otherwise. From The Swift Programming Language, Automatic Reference Counting:

    … closures, like classes, are reference types. When you assign a closure to a property, you are assigning a reference to that closure.

    (That's why capture lists exist: to help avoid accidental retain cycles.)

    However, I think you may be misunderstanding the purpose of @escaping (or the absence of @noescape in older version of Swift). This does not automatically save the closure for you. Rather, it just indicates to the caller that you might save the closure (that the closure might escape the execution of the function). This allows the compiler to perform extra optimizations, such as skipping the retain. It also allows callers to omit self. inside the closure:

    class Foo {
        var x = 3
    
        func test() {
            [1, 2, 3].map { $0 + x }
            // `self.x` is not necessary, because the map function's
            // closure is non-escaping
        }
    }
    

    (If you're interested in learning what's really going on under the hood with @escaping, I don't know of a definitive source for this kind of information, but you might find some useful things in this talk about SIL, the SIL.rst docs in the open-source project, and perhaps Understanding Swift Performance from WWDC16.)

    0 讨论(0)
提交回复
热议问题