要理解@escaping,首先需要理解closure, 要理解closure,首先理解匿名函数。
先理解匿名函数
要在Swift中构造匿名函数,需要:
func whatToAnimate(){
self.myButton.frame.origin.y += 20
}
匿名函数版本:
{
() -> () in
self.myButton.frame.origin.y += 20
}
例子2: 有参数的具名函数:
func whatTodoLater(finished: Bool){
print("finished: \(finished)")
}
匿名函数版本:
{
(finished: Bool) -> () in
print("finished: \(finished)")
}
可省略的地方:
- 省略返回类型
- 没有参数可以省略 in 这一样
- 省略参数类型
- 省略圆括号,这个是如果就一个参数,并且我们编译器可以推断出其类型的话
- 省略 in, 直接用名字比如 $0
- 省略参数名,用_代替
- 省略函数实参标签(又叫尾函数
...
一路省略下来,匿名函数真是节约。
再理解闭包
理解匿名函数之后,我们来看闭包的表达式:
{ (parameters) -> return type in
statements
}
这就是匿名函数啊,而我们叫它闭包则是因为:
闭包可以捕获和存储其所在上下文中任意常量和变量的引用。 这就是所谓的闭合并包裹着这些常量和变量,俗称闭包。
而在这一篇中,我们可以一步一步看到如何从
reversed = sorted(names, { (s1: String, s2: String) -> Bool in
return s1 > s2
})
利用省略到:
reversed = sorted(names, >)
再利用 trailling closure的特性,可以这样:
reversed = sorted(names) { $0 > $1 }
闭包当然还有更好的例子,因为我们来看它的一些特性。
Escaping Closure(逃逸闭包
好抽象的描述,这篇文章写得不错:
不逃逸闭包的生命周期:
- Pass a closure into a function
- The function runs the closure (or not)
- The function returns
然后这个closure就死掉了。
而逃逸闭包则会一直存在,没有因为function被kill而死掉,所以我们叫这个闭包为逃逸闭包(?
在以下的两种情况,我们需要使用 escaping closure:
- 异步execution,并不能说函数return了就把closure kill掉,因为这个closure可能还没有执行完毕
- 存储,如果任何全局变量都有一些些存储存在,那么这个closure也被逃逸掉了。
在 Swift 1 和 2中, closure by default 是 escaping的,所以我们需要用 @noescape 来mark.
在 Swift 3中,closure by default是non-escaping,我们需要用@escaping 来mark
In Swift 3, closure parameters are non-escaping by default; you can use the new @escaping attribute if this isn’t what you want. Non-escaping closures passed in as arguments are guaranteed to not stick around once the function returns.
而一般情况下,弱
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。