The understanding of escape closures in Swift

Source: Internet
Author: User
Tags closure
written definition of escape closure

A closure of an incoming function is called an escape closure if it is not invoked until after the function has finished executing. The understanding of the definition

By definition we know that the escape closure is first a closure (it feels a bit of nonsense), but the escape closure is not an ordinary closure because it will execute after the function is finished (this is the feature). What closures do not execute after a function is executed?

Many functions that initiate asynchronous operations accept a closure parameter as completion handler. This type of function that initiates an asynchronous operation returns immediately after the start of the asynchronous operation (that is, the function of the "initiate asynchronous Operation" has completed), but the closure is not invoked until after the end of the asynchronous operation (that is, the "Start asynchronous operation" function is finished executing). This is a perfect match for the definition of escape closures ...
Look at an example:

var completionhandlers: [()-> Void] = []
func somefunctionwithescapingclosure (completionhandler: @escaping ()-& Gt Void) 
{
    completionhandlers.append (completionhandler)
}

The above code defines a global variable completionhandlers the global variable is an array that is internally designed to hold closures with no parameters and no return values, while defining function Somefunctionwithescapingclosure, This function receives a closure and adds the closure to the external global array. Then the function ends (note: The incoming closure is not executed, just added to the global array).

Next, refine the code above:

Defines a global array containing closures
var completionhandlers: [()-> Void] = []

//define a function to receive closures
func Somefunctionwithescapingclosure (Completionhandler: @escaping ()-> Void) 
{
    completionhandlers.append ( Completionhandler)
}

//define another function to receive closures
func somefunctionwithnonescapingclosure (Closure: ()-> Void) {
    closure ()
}
/* Define a class:
Initialize x values
by calling the two functions defined above, using a trailing closure method will implement the "x assigned to" Such a function of the closure of the closed-loop incoming
* * *
class SomeClass {
    var x = Ten
    func dosomething () {
        somefunctionwithescapingclosure {self.x = m}
        somefunctionwithnonescapingclosure {x = +}
    }

//Create object for class let
instance = SomeClass ()/

*
perform the dosomething function
PS: Internal execution somefunctionwithescapingclosure,somefunctionwithnonescapingclosure, that is, expect to use two trailing closures to assign value to x
* *
Instance.dosomething () print
(instance.x)
//Print out "the"

Completionhandlers.first? ()
Print (instance.x)
//Printing out "100"

Looking at the output of this code, I was very surprised at first, because the escape closure is not understood, so it is difficult to understand why the second print will output is 100. explanation of code execution results

Since the escape closure is performed after the function executes, it is understandable that I created an object in the class instance object that initializes an X = 10 using the object to perform the function dosomething The function is called the global function somefunctionwithescapingclosure the function passed in the trailing closure {self.x = 100}, Expect to modify the X value in the instance object to 100 (but not at this time the closure that contains the assignment statement) function calls the global function somefunctionwithnonescapingclosure the function passed in the trailing closure {x = 200}. The x value in the instance object is expected to be modified by 200 (because at this point the global function Somefunctionwithnonescapingclosure internally executes the closure containing the assignment statement, so the value of x is changed from 10 to 200) output (obviously 200) Find the global array completionhandlers, find the first element inside, and obviously find the closure {self.x = 100} added to the Somefunctionwithescapingclosure function. At this point the global array of queries to find the closure and execution, so x at this time is assigned to 100 (the typical somefunctionwithescapingclosure function after the execution of the closure {self.x = 100}, So the closure that was last executed after the function was the definition of the escape closure. Conclusions

The escape closure will be executed after the function executes, so the code finally prints 100 because the closure was last executed ...

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.