Swift相关:
1、闭包的定义
一个函数和它所捕获的变量、常量环境组合起来,被称为闭包
注意:
- 这里的函数一般指定义在函数内部的函数
- 一般捕获的是外层函数的局部变量、常量
func makeClosure() -> (Int) -> Int {
var temp = 1
func closure(_ number:Int) -> Int {
temp += number
return temp
}
return closure //返回的makeClosure和one形成了闭包
}
- 内存在堆空间
- 捕获的局部变量、常量就是对象的成员(存储属性)
- 组成闭包的函数就是类内部定义的方法
闭包是自包含的功能代码块,跟C和OC中的代码块(block)和其他一些语言中的匿名函数相似
- 闭包可以作为函数的参数也可以作为函数的返回值
- 可以向
OC中一样用于回调和反向传值
2、闭包表达式
{(param1, param2) -> (returnType) in
// code
}
- 参数有多个时,多个参数用逗号隔开
- 参数列表的小括号可以省略
- 返回值类型也可以省略
- 当没有返回值是
in可以省略 in可以看做是一个分隔符,将函数体和前面的参数、返回值分隔开
2.1、闭包作为变量或常量
var closure1: (_ num1: Int, _ num2: Int) -> Int = {(num1, num2) -> Int in
return num1+num2
}
let closure2: (_ num: Double) -> Double = { num -> Double in
return num
}
var x = closure1(10, 20)
var y = closure2(200.0)
var closure : (Int) -> Int? // 错误
var closure : ((Int) -> Int)? = nil // 正确
2.2、闭包作为函数的参数
func closureFunc(param:(_ num1: Int, _ num2: Int) -> Int) {
print("ret:\(param(100, 200))") // 100
}
closureFunc(param: {(num1, num2) -> Int in
print("\(num1),\(num2)")
return num1+num2
})
2.3、闭包作为返回值
var closure: (_ a: Int) -> Int
func closureFunc(_ a: Int, _ b: Int) -> (_ a: Int) -> Int {
return closure
}
3、尾随闭包
当我们把闭包表达式作为函数的最后一个参数,如果当前的闭包表达式很长,我们可以通过尾随闭包的书写方式来提高代码的可读性
func closureFunc(_ a: Int, _ b: Int, _ by:(_ x:Int) -> Int) {
var num = by(20)
}
closureFunc(20, 20){ x in
return x
}
var array = [1, 2, 3]
array.sort(by: {(item1 : Int, item2: Int) -> Bool in return item1 < item2 })
array.sort(by: {(item1, item2) -> Bool in return item1 < item2 })
array.sort(by: {(item1, item2) in return item1 < item2 })
array.sort{(item1, item2) in item1 < item2 }
array.sort{ return $0 < $1 }
array.sort{ $0 < $1 }
array.sort(by: <)
4、闭包捕获值
func make() {
var i = 1
let closure: (_ a: Int) -> () = { a in
i += a
print("closure:\(i)")
}
print(i)
closure(1)
print("after1:\(i)")
closure(1)
print("after2:\(i)")
}
make()
//输出结果
1
closure:2
after1:2
closure:3
after2:3
在闭包调用捕获外部局部变量的时候,是把值捕获到了堆区,在使用的时候直接访问地址拿到的值。
- 闭包可以在方法调用的时候捕获上下文中的常量或变量。
- 即使这个方法的作用域已经不在,仍然可以修改捕获到的变量
4.1、全局变量和局部变量捕获时的区别
闭包在使用全局变量的时候不会捕获到闭包内部,而在使用局部变量的时候会捕获到闭包的内部再使用