前言
- 函数类型作为变量,可以接收函数。
- 函数类型作为返回值, 可以返回函数。
- 函数类型作为参数,这就是闭包。
闭包
- 闭包的写法有很多
- 如果是尾随闭包,可以把闭包放到小括号的后边。如果这时候小括号里边没有参数了可以去掉小括号
- 参数类型和返回类型可以省略
- 参数可以省略用$0,$1表示
- 如果是单一的表达式可以省略return关键字
var a = ["2", "3", "1", "0", "4", "6"]
// 1. 普通写法
var b = a.sorted(by: { (x: String, y: String) -> Bool in
return x > y
})
//2. 闭包尾随写法
var b1 = a.sorted{ (x: String, y: String) -> Bool in
return x > y
}
//3. 省略参数类型,返回类型写法
var b2 = a.sorted{ (x, y) in
return x > y
}
//4. 省略参数写法
var b3 = a.sorted{
return $0 > $1
}
//5. 单个表达式省略return写法
var b4 = a.sorted{$0 > $1}
//6. >号写法
var b5 = a.sorted(by: >)
print("b = \(b)")
//数组每个元素映射
let digitNames = [
0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four",
5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
let numbers = [16, 58, 510]
let numStr = numbers.map { (number) -> String in
var num = number
var total = ""
repeat {
let temp = num%10
total = digitNames[temp]! + total
num /= 10
}while num > 0
return total
}
print(numStr)
- 值的捕获
嵌套函数也是一种闭包,闭包可以捕获值
func addOneFunc(value:Int) -> () -> Int{
var total = 0
func addOne() -> Int{
total += value
return total
}
return addOne
}
var a = addOneFunc(value: 10)
print(a())
print(a())
print(a())
print(a())
print(a())
var b = addOneFunc(value: 5)
print(b())
print(b())
print(b())
print(b())
print(b())
- 逃逸闭包
- 逃逸闭包是指函数返回后才会执行的闭包
- 多线程中,函数已经返回,子线程才开始执行闭包,那这个闭包就需要逃逸
- 逃逸闭包入参要写标注@escaping
- 逃逸闭包在调用时候要显示的写self
var arr = [() -> Void]()
func escapingClosureFunc(closure: @escaping () -> Void){
arr.append(closure)
}
func noescapingClosureFunc(closure: () -> Void){
closure()
}
class SomeClass {
var x = 10
func doSomething() {
escapingClosureFunc {
self.x = 100
}
noescapingClosureFunc {
x = 200
}
}
}
var instance = SomeClass()
instance.doSomething()
print(instance.x)
arr.first?()
print(instance.x)
- 自动闭包
- 自动闭包有延时执行作用
//逃逸闭包可以延时执行 (变量)
var arr = ["a", "b", "c", "d", "e", "f", "g", "h"]
var removeFirst = {arr.removeFirst()}
print(removeFirst())
//["b", "c", "d", "e", "f", "g", "h"]
//入参
func removeFirstFunc(closure: () -> String){
print(closure())
}
removeFirstFunc(closure: {arr.removeFirst()})
//["c", "d", "e", "f", "g", "h"]
//自动闭包入参
func removeFirstFuncAuto(closure: @autoclosure () -> String){
print(closure())
}
removeFirstFuncAuto(closure: arr.removeFirst())
//["d", "e", "f", "g", "h"]
//逃逸自动闭包
var arrClosure: [() -> String] = []
func escapingAutoClosure(closure: @escaping @autoclosure () -> String){
arrClosure.append(closure)
}
escapingAutoClosure(closure: arr.removeFirst())
escapingAutoClosure(closure: arr.removeFirst())
print(arr)
arrClosure.first?()
arrClosure.first?()
print(arr)
//["f", "g", "h"]