The concept of escape needs to be introduced here. A closure is said to have escaped from a function when passed as an argument and executed after the function has finished executing it. This scenario is very common, such as when we make an asynchronous request, the request will be passed to a handler, such as when the request is successful to achieve the purpose of the callback.

Swift’s memory management is known as reference counting. All data used in a closure needs to be captured in the closure to ensure that it is not released and stored in memory when the closure is executed. To make us realize that the object used in the closure is already retained, Xcode requires us to display the declaration self when accessing the current property. It is easy for beginners to make the mistake of referring to a loop. Closure retain self, self if hold retain closure. Eventually, no one can release it, and the memory leaks.

This is how the default closure is used in Swift. But there is another possibility here, assuming that there is a closure passed in for sort, or for example as a map parameter. When this line of code is finished executing, the closure is finished and will not be executed again. In this case, the closure doesn’t have to hold the objects it uses. This is the non-escape closure.

Swift is denoted by @noescape for non-escape. For example, the map function uses:

func map(@noescape transform: (Self.Generator.Element) throws -> T) rethrows -> [T]Copy the code


And the nice thing you can see after you tag this is that you don’t have to add it if you’re using self again inside this closure
self.. For the compiler, there are some memory optimizations that can be made once the noescape closure is known.

Welcome to my micro blog: @Zhuo who has no story