闭包表达式
import Foundation
func backward(_ a: Int, _ b: Int) -> Bool {
return a > b
}
var lst = [5, 3, -1, 9]
print(lst.sorted(by: backward))
import Foundation
var lst = [5, 3, -1, 9]
print(lst.sorted(by: { (a: Int, b: Int) -> Bool in
return a > b
}))
import Foundation
var lst = [5, 3, -1, 9]
print(lst.sorted(by: { a, b in return a > b }))
import Foundation
var lst = [5, 3, -1, 9]
print(lst.sorted(by: { a, b in a > b }))
import Foundation
var lst = [5, 3, -1, 9]
print(lst.sorted(by: {$0 > $1})) //$0表示第一个参数
import Foundation
var lst = [5, 3, -1, 9]
print(lst.sorted(by: >))
尾随闭包
当花括号中的内容比较复杂时,将花括号作为一个整体提到圆括号的外面,以增加程序的可读性
import Foundation
var lst = [5, 3, -1, 9]
print(lst.sorted(){a, b -> Bool in a > b})
捕获值
import Foundation
func makeinc(_ a: Int) -> () -> Int {
var r = 0
func inc() -> Int {
r += a // 闭包是引用类型,因此每次调用byten时r都会在上一次的基础增加
return r
}
return inc
}
let byten = makeinc(10)
print(byten())
print(byten())
print(byten())
print(byten())
let bynine = makeinc(9)
print(bynine())
print(bynine())
print(bynine())
print(bynine())
import Foundation
func makeinc(_ a: Int) -> () -> Int {
var r = 0
func inc() -> Int {
return r + a // s这里的闭包仅仅只是返回一个值,并没有改变r的值,因此每次调用byten的时候,r都是初始值0
}
return inc
}
let byten = makeinc(10)
print(byten())
print(byten())
print(byten())
print(byten())
let bynine = makeinc(9)
print(bynine())
print(bynine())
print(bynine())
print(bynine())
逃逸闭包
//定义一个存放闭包的全局数组,注意这里是全局变量
var completionHandlers: [() -> Void] = []
//定义一个接收闭包的函数
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) //这里必须要加escaping,不然就会报错,这是逃逸的一种方式,将闭包存储在函数外的全局变量里,在函数调用后闭包才会执行
{
print("111")
print("first" + "\(instance.x)") // 输出first10
completionHandlers.append(completionHandler)// 把闭包存进去,但是不执行闭包,因为闭包是逃逸的,要在函数结束之后才能使用,因此x还是10
print("second" + "\(instance.x)")// 所以这里输出的依旧是second10
print("222")
}
//定义另一个接收闭包的函数
func someFunctionWithNonescapingClosure(closure: () -> Void) {
closure() //这个函数传入一个闭包,名字叫做closure,这个闭包是非逃逸闭包,即该闭包的生命周期就是就是一定小于等于函数的生命周期,函数结束了这个闭包就被释放了,所以非逃逸闭包一定是在函数的生命周期内执行的,不可能晚于函数的生命周期
}
/*
定义一个类:
初始化x值为10
通过调用上面定义的两个函数,使用尾随闭包的方式将实现"对x赋值"这么一个功能的闭包传入
*/
class SomeClass {
var x = 10
func doSomething() {
someFunctionWithEscapingClosure { self.x = 100 }
print("aaa\(x)")
someFunctionWithNonescapingClosure { x = 200 }
print("bbb\(x)")
}
}
//创建类的对象
let instance = SomeClass()
instance.doSomething()
print(instance.x)
completionHandlers.first?() //first表示第一个元素,这个元素的类型是() -> void,因此函数名就是first,所以问号要直接跟在first后面,因为数组可能为空,所以这里可能会返回nil,所以要加一个可选类型?
print(instance.x)