逃逸闭包(@escaping) 当前方法大括号执行结束之后执行。最常见的就是网络请求类中

我们先看一个例子

override func viewDidLoad() {
            super.viewDidLoad()
            changedMap { (source) in
                print("逃逸闭包拿到的结果是\(source)")
            }
        }

      func changedMap(block: @escaping (_ result: Int) ->Swift.Void){
            DispatchQueue.global().async {
                print("逃逸闭包异步的走\(Thread.current)")
                DispatchQueue.main.async {
                    print("逃逸闭包主线程的走\(Thread.current)")
                    block(99)
                }
            }
            print("逃逸闭包结束了的走")
        }

上边这个例子中闭包采用的@escaping修饰为逃逸闭包。那么这样使用的话,代码的执行顺序如何呢。请看下边打印

逃逸闭包结束了的走
逃逸闭包异步的走<NSThread: 0x60000026fc00>{number = 4, name = (null)}
逃逸闭包主线程的走<NSThread: 0x60c000065100>{number = 1, name = main}
逃逸闭包拿到的结果是99

我们看着打印的去理解这段代码是不是简单的多了。因为方法是异步执行的,所有当调用当前方法的时候会先走

1.逃逸闭包结束了的走. 那这个走过之后代码会异步执行
2.逃逸闭包异步的走{number = 4, name = (null)} 这个时候在异步线程中出现了回到主线程方法因此走
3.逃逸闭包主线程的走{number = 1, name = main} 因为我们要的结果是异步执行返回的因此最后走
4.逃逸闭包拿到的结果是99

非逃逸闭包(@noescape) 方法顺序执行,闭包走完方法才会执行结束

eg

override func viewDidLoad() {
            super.viewDidLoad()
            ourceMap { (source) in
                print("非逃逸闭包拿到的结果是\(source)")
            }
        }



   func sourceMap(block: (_ result: Int) -> Swift.Void) {
            print("非逃逸闭包主线程的走\(Thread.current)")
            block(99)
            print("非逃逸闭包结束了的走")
        }

对于swift来说,闭包默认使用的就是非逃逸类型进行修饰的
我们看下打印结果

非逃逸闭包主线程的走<NSThread: 0x60800006a280>{number = 1, name = main}
非逃逸闭包拿到的结果是99
非逃逸闭包结束了的走

不难理解,方法执行是在主线程进行,因此

1.非逃逸闭包主线程的走{number = 1, name = main} 我们直接在方法中返回了闭包,因此
2.非逃逸闭包拿到的结果是99 这时拿到了我们的结果。 继续往下执行
3.非逃逸闭包结束了的走. 结束当前非逃逸闭包函数执行