逃逸闭包(@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.逃逸闭包异步的走<NSThread: 0x60000026fc00>{number = 4, name = (null)} 这个时候在异步线程中出现了回到主线程方法因此走
3.逃逸闭包主线程的走<NSThread: 0x60c000065100>{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.非逃逸闭包主线程的走<NSThread: 0x60800006a280>{number = 1, name = main} 我们直接在方法中返回了闭包,因此
2.非逃逸闭包拿到的结果是99 这时拿到了我们的结果。 继续往下执行
3.非逃逸闭包结束了的走. 结束当前非逃逸闭包函数执行
网友评论