一个常见的闭包表达式语法

{ (parameters) -> return type in
    statements
}

闭包的函数体部分由关键字 in 引入。该关键字表示闭包的参数和返回值类型定义已经完成,闭包函数体即将开始

reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
    return s1 > s2
})

sorted方法被字符串数组调用,所以类型可以省略,同时 return 也可以省略,最终见下

reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )

既然都省略成这样了,那么两个参数当然可以省略,同时in也可以省略

reversedNames = names.sorted(by: { $0 > $1 } )

坑不坑,看不下去了..

尾随闭包

对比以下两个闭包写法

正常写法

someFunctionThatTakesAClosure(closure: {
    // 闭包主体部分
})

可读性强的尾随闭包写法

// 以下是使用尾随闭包进行函数调用
someFunctionThatTakesAClosure() {
    // 闭包主体部分
}

上面两种写法是一样的效果,尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。在使用尾随闭包时,你不用写出它的参数标签.

尾随闭包的调用,结构很像一个方法体.其实是一个方法调用

所以,swift简写起来简直不要命,能省的全省了,还是之前的排序闭包例子,利用尾随闭包,可以这样写

reversedNames = names.sorted() { $0 > $1 }

如果只有一个闭包参数,小括号可以省略,所以完全体如下

reversedNames = names.sorted { $0 > $1 }

不过当闭包非常长以至于不能在一行中进行书写时,尾随闭包变得非常有用

无论你将函数或闭包赋值给一个常量还是变量,你实际上都是将常量或变量的值设置为对应函数或闭包的引用

逃逸闭包

当一个闭包作为参数传到一个函数中,但是这个闭包在函数返回之后才被执行,我们称该闭包从函数中逃逸。当你定义接受闭包作为参数的函数时,你可以在参数名之前标注 @escaping,用来指明这个闭包是允许“逃逸”出这个函数的

一些异步请求,函数会立即返回,而闭包会在拿到数据之后才会调用,这就是典型的逃逸闭包

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

将一个闭包标记为 @escaping 意味着你必须在闭包中显式地引用 self

标签: Swift, 从Objective-C到Swift, 闭包, block

添加新评论