Swift之自动闭包(@autoclosure、@noescape、@escape)
来源:互联网 发布:九号文件 知乎 编辑:程序博客网 时间:2024/06/11 12:43
先了解一些简单知识点,@autoclosure也就是自动闭包:
1:自动闭包,顾名思义是一种自动创建的闭包,用于包装函数参数的表达式,可以说是一种简便语法.
2:自动闭包不接受任何参数,被调用时会返回被包装在其中的表达式的值。
3:自动闭包的好处之二是让你能够延迟求值,因为代码段不会被执行直到你调用这个闭包,这样你就可以控制代码什么时候执行。
4:含有autoclosure特性的声明同时也具有noescape的特性,及默认是非逃逸闭包,除非传递可选参数escaping.如果传递了该参数,那么将可以在闭包之外进行操作闭包,形式为:请使用@autoclosure(escaping)。
下面一起来看一个简单例子:比如我们有一个方法接受一个闭包,当闭包执行的结果为true的时候进行打印:
func printIfTrue(predicate: ()-> Bool){ if predicate(){ print("the result is true") }}//1直接调用方法printIfTrue { () -> Bool in return 2 > 1}//2闭包在圆括号内printIfTrue({ return 2 > 1 })//3:使用尾部闭包方式,闭包体在圆括号之外printIfTrue(){ return 2 > 1 }//4:在 Swift 中对闭包的用法可以进行一些简化,在这种情况下我们可以省略掉 return,写成:printIfTrue({ 2 > 1})//5:还可以更近一步,因为这个闭包是最后一个参数,所以可以使用尾随闭包 (trailing closure) 的方式把大括号拿出来,然后省略括号,变成:printIfTrue{2 > 1}
但是不管哪种方式,表达上不太清晰,看起来不舒服。于是@autoclosure就登场了。我们可以改换方法参数,在参数名前面加上@autoclosure关键字:
func printIfTrue(@autoclosure predicate: ()-> Bool){ if predicate(){ print("the result is true") }}printIfTrue(2 > 1)//直接进行调用了,Swift 将会把 2 > 1 这个表达式自动转换为 () -> Bool。这样我们就得到了一个写法简单,表意清楚的式子。
如果有多个闭包,那么就有优势了,而@autoclosure是可以修饰任何位置的参数:
func printInformation(@autoclosure predicate1: ()-> Bool,@autoclosure predicate2: ()-> Bool){ if predicate1() && predicate2(){ print("the result is true") }else{ print("the result is false") }}printInformation( 3 > 2, predicate2: 4 > 1)
@noescape和 @escape
对于autoclosure属性来讲,还有2个相关的属性要了解一下。也就是@noescape和@escape。这2个属性都是用来修饰闭包的。@noescape意思是非逃逸的闭包,而@escape则相反。默认情况下,闭包是@escape的。表示此闭包还可以被其他闭包调用。比如我们常用的异步操作:
func executeAsyncOp(asyncClosure: () -> ()) -> Void { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { asyncClosure() }}
其中asyncClosure在dispatch_async中的闭包中调用,完成异步的操作。因为闭包默认是@escape的,以上代码是可以运行的。但是当我们在asyncClosure前面加入@noescape属性时候,编译器就会报错:
func executeAsyncOp(@noescape asyncClosure: () -> ()) -> Void { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { asyncClosure() }}error:closure use of @noescape parameter 'asyncClosure' may allow it to escape asyncClosure()
@noescape属性是在 Swift1.2中引入的,把传入闭包参数的调用限制在调用的函数体内,对性能有一定的提升,同时将闭包标注为@noescape使你能在闭包中隐式地引用self。
在 Swift标准库中很多方法,都用了@noescape属性,比如 Array对应的方法 map,filter和 reduce:
func map<T>(@noescape transform: (Self.Generator.Element) -> T) -> [T]func filter(@noescape includeElement: (Self.Generator.Element) -> Bool) -> [Self.Generator.Element]func reduce<T>(initial: T, @noescape combine: (T, Self.Generator.Element) -> T) -> T
- Swift之自动闭包(@autoclosure、@noescape、@escape)
- [绍棠_Swift] Swift中的@noescape @escaping @autoclosure
- Swift中autoclosure和noescape关键字
- @noescape @escaping @autoclosure
- @noescape @escaping @autoclosure
- 使用@noescape解决Swift闭包“保留环”问题
- [swift学习之六]@autoClosure练习
- Swift学习之每日一tip (5)@autoclosure
- swift @noescape有啥卵用
- Swift中@noescape介绍
- Swift中@noescape介绍
- Swift之闭包
- Swift之闭包
- Swift之闭包
- 使用@autoclosure提高Swift代码质量
- Swift学习之闭包
- swift学习之闭包
- swift学习之- 闭包
- 2015-5-12-2
- 【DP动态规划】个人常用基础动态规划DP小总结【TODO】
- 如何将Emmet安装到到 Sublime text 3?
- 用 JMockit 编程测试代码
- Git忽略规则及.gitignore规则不生效的解决办法
- Swift之自动闭包(@autoclosure、@noescape、@escape)
- Android通用流行框架大全
- 浏览器前进后退时不缓存请求服务器
- ZeroMQ消息模型代码实现(Python版本)
- 扯扯淡
- 限制性关键值
- build/envsetup.sh
- json直接转成Java能用的变量
- Ubuntu配置tftp服务器