Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的 匿名函数比较相似。现在简单认识下Swift 中的闭包
闭包的形式一般为:
let Closure = {(parameters) -> returntype in
statements
}
举个例子:
let add = {(a: Int, b: Int) -> Int in
return a + b
}
let result = add(1, 2)
Swift中的闭包有很多可以优化
比如根据上下文推断参数和返回值类型,我们可以优化成
let add = {(a, b) -> Int in
return a + b
}
let result = add(1, 2)
比如从单行表达式闭包中隐式返回(也就是闭包体只有一行代码,可以省略return)
let add = {
(a:Int,b:Int) in a+b
}
let result = add(1,2)
也可以这样:
let add:(Int,Int) ->Int = {
(a,b) in a + b
}
let result = add(1,2)
还可以使用简化参数名,如$0, $1(从0开始,表示第i个参数…)
let add:(Int,Int) ->Int = {
return $0+$1
}
let result = add(1,2)
Swift的尾随闭包
例子:
func testFunction(testBlock: ()->Void){
testBlock()
}
testFunction(testBlock: {
print("尾随闭包")
})
也可简写成
//推荐写法
testFunction {
print("尾随闭包")
}
相当于在Objective-C中
- (void)testFunction:(void(^)())testBlock{
testBlock();
}
[self testFunction:^{
}];
嵌套函数,也就是定义在其他函数的函数体内的函数。
嵌套函数可以捕获其外部函数所有的参数以及定义的常量和变量。
例子:
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
一个函数makeIncrementor ,它有一个Int型的参数amout, 并且它有一个外部参数名字forIncremet,意味着你调用的时候,必须使用这个外部名字。返回值是一个()-> Int的函数。
函数题内,声明了变量runningTotal 和一个函数incrementor。
incrementor函数并没有获取任何参数,但是在函数体内访问了runningTotal和amount变量。这是因为其通过捕获在包含它的函数体内已经存在的runningTotal和amount变量而实现。
由于没有修改amount变量,incrementor实际上捕获并存储了该变量的一个副本,而该副本随着incrementor一同被存储。
let incrementByTen = makeIncrementor(forIncrement: 10)
// 返回的值为10
print(incrementByTen())
类的属性也可以用闭包表示
var name:String{
get{
return "Joe"
}
set{
println("name")
}
}
下面看看闭包的使用,以cell为例
typealias didSeletctBlock=(MyModel) -> Void
//类似 oc 里的 typedef void (^didSeletctBlock)(MyModel *)
class CustomCell: UITableViewCell {
var didSeletctBlock :didSeletctBlock?
//var testBlock:((_ model:MyModel) -> ())?
@IBAction func onClickButton(_ sender: Any) {
if didSeletctBlock != nil {
didSeletctBlock!(myModel)
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:CustomCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
cell.didSeletctBlock = {
model in
print(model.name)
}
// cell.testBlock = {
// (model:MyModel) -> () in
// print(model.name)
// }
return cell
}
我们初步了解了Swift里的闭包,其实在其他语言里也会用到闭包,比如在JavaScript中所有的function都是一个闭包。
例子
function a() {
var i = 0;
function b() {i++; }
return b;
}
var c = a();
c();
1、函数b嵌套在函数a内部;
2、函数a返回函数b。
3、当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。