闭包就是一段代码块,可以捕获其上下文的变量。
闭包的定义
{ (parameters) -> return type in
statements
}
可以用一个变量保存闭包
let clou1 = {(str1:String, str2:String) -> String in
print(str1)
return str1 + str2
}
clou1("12", "34") // "1234"
//指定闭包类型
let clou2:(String, String) -> String = {(str1, str2) in
return str1 + str2
}
clou2("hello ", "world")
闭包作为函数的最后一个参数
func walk(clou:() -> Void) {
clou()
print("sss")
}
//调用时的形式有以下2种
walk(clou: {
print("222")
})
walk() {
print("222")
}
值捕获
定义在函数内的闭包可以捕获函数中的变量和常量以及参数值
func makeIncrementer(amount: Int) -> () -> Int {
var runningTotal = 0
return {() -> Int in
runningTotal += amount
return runningTotal
}
}
let incrementByTen = makeIncrementer(amount: 10)
incrementByTen() //10
incrementByTen() //20
incrementByTen() //30
逃逸闭包(Escaping Closures)
A closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns.
闭包需要在函数执行结束后才执行,需要在闭包参数类型前加@escaping
func escapClosures(testClou:@escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5) {
testClou()
}
}
escapClosures() {
print("sfsdfs")
}
逃逸闭包中如果引用到实例变量,需要显示调用self
,非逃逸闭包则不需要。
func testEscapingClosures(myCloures: @escaping () -> Void) {
print("ssss")
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
myCloures()
}
}
func testNoEscapingClosures(myCloures: () -> Void) {
myCloures()
}
testEscapingClosures() {
//逃逸闭包中引用实例变量,要显示指明self
print("now num is \(self.num)")
}
testNoEscapingClosures {
//非逃逸闭包,不用显示指明self
print("no escaping, num is \(num)")
}
网友评论