Closures only distinguish between escape closures and non escaping closures when they are parameters in a function
After Swift 3, when transitive closures into functions, the system defaults to the non-escape closure type (nonescaping Closures) @noescape, and there must be escape closures for non-escape closure types escaping Closures), escape closure to add the @escaping keyword before closing the package
Life cycle of non-escape closures: 1. The closure is passed as a parameter to the function; 2. The closure is invoked in the function; 3. Exit function, Closure life cycle end
That is, the life cycle of a non-escape closure is the same as the function
Life cycle of escape closure: 1. The closure is passed as a parameter to the function; 2. Exit function; 3. Closure is invoked, closure life cycle ends
That is, the life cycle of the escape closure is longer than the function, and when the function exits, the escape closure reference is still held by other objects and will not be released at the end of the function.
Example:
Non-escape closures:
Import Uikit
Class Httptool:nsobject {
1 func loaddata (callBack: ((String)-> ()) {
2 CallBack ("Non-escape closure")
3}
}
Viewcontroller class:
Import Uikit
Class Viewcontroller:uiviewcontroller {
Override Func Viewdidload () {
Super.viewdidload ()
}
var tools:httptool = Httptool ()
Override Func Touchesbegan (_ Touches:set<uitouch>, with Event:uievent?) {
Tools.loaddata {(jsondata:string) in
Print (Jsondata);
}
}
}
Code Execution Order 1,2,3
When passing the closure parameter to the function LoadData, be aware of the property tools in the Viewcontroller, although the closure captures self, but because the default closure parameter is not escape type, you can omit self because the compiler already knows there is no potential risk of circular references here.
Escape closure:
Import Uikit
Class Httptool:nsobject {
Func loaddata (CallBack: @escaping ((String)-> ()) {
1 Dispatchqueue.global (). async {
DispatchQueue.main.async {
2 CallBack ("This is escape closure")
}
}
3}
}
Viewcontroller class:
Import Uikit
Class Viewcontroller:uiviewcontroller {
Override Func Viewdidload () {
Super.viewdidload ()
}
var tools:httptool = Httptool ()
Override Func Touchesbegan (_ Touches:set<uitouch>, with Event:uievent?) {
Tools.loaddata {(jsondata:string) in
Print (Jsondata);
}
}
}
Code Execution Order 1,3,2
When passing the closure parameter to the function LoadData, pay attention to the property tools in Viewcontroller, where the life cycle of the closure function ends at the end of the function, and the self that is omitted before the tools is necessary for special treatment to prevent the death cycle.
Escape closure To add the @escaping keyword before the closure, where the closure life cycle is unpredictable
2 scenarios that often use escape closures: Asynchronous Invocation : If you need to dispatch a queue to call a closure asynchronously, such as a successful callback and a failed callback for a network request, the queue holds a reference to the closure, and when the closure is invoked, or when the closure is run, the above example is not certain. storage : Need to store closures as attributes, global variables or other types to do later use, examples to add.
Later useful to escape closure of the example, will be updated in time, but also welcome to see the small partners to help supplement