闭包(Closures)是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。
Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的 匿名函数比较相似。
全局函数和嵌套函数其实就是特殊的闭包
Swift中的闭包有很多优化的地方:
- 根据上下文推断参数和返回值类型
- 从单行表达式闭包中隐式返回(也就是闭包体只有一行代码,可以省略return)
- 可以使用简化参数名,如
1(从0开始,表示第i个参数...)
- 提供了尾随闭包语法(Trailing closure syntax)
闭包的语法结构🌟🌟🌟🌟
{(参数列表)-> in 闭包体 返回值}
//声明 var myclosure : () -> Void
var myclosure : () -> Void = {
}
var mySecondClosure:(Int,Int) ->Int = {(a:Int,b:Int) in
return a+b
}
闭包的七种写法
1. 闭包参数类型省略() mySecondClosure2 已经声明函数类型为(int,int),所以后面的闭包里面的参数类型可以自动推导出来,
var mySecondClosure2:(Int,Int) ->Int = {(a,b) in
return a+b
}
2. return 省略 如果闭包只有一行代码组成,return关键字也可以省略,默认会将此行代码的执行结果返回
var mySecondClosure3:(Int,Int) ->Int = {(a,b) in
a+b
}
3. 使用自动生成的参数($0
,$1
)闭包的参数列表会自动生成一族参数,参数名称会以$0
,$1
这样的结构以此类推,开发者也可以使用默认参数名
var mySecondClosure4:(Int,String) ->Int = {
let IntStr:Int? = Int($1)
return $0+IntStr!
}
4. <后置闭包> 当函数的最后一个参数为闭包时参数时,在调用函数时,开发者可以将闭包结构脱离函数列表,追加在函数的尾部
func mystudentBlock(student:(Int,Int)->Int,a:Int) -> Int {
//{(b:Int,c:Int)in return b+c}
return a * student(10,20)
}
/* 正常使用
mystudentBlock(student: { (a, b) -> Int in
return a+b
}, a: 20)
*/
func mystudentBlock1(a:Int,student:(Int,Int)->Int) -> Int {
//{(b:Int,c:Int)in return b+c}
return a * student(10,20)
}
/* 脱离参数列表的使用
mystudentBlock(a: 10) {(a,b) in
return a+b
}
*/
5. < 逃逸闭包> 函数内的闭包在函数执行结束之后在函数的外面依然可以调用,使用@escaping修饰,主要用于网络请求回调
// @escaping 表示逃逸的 闭包不是在当前方法中使用,但是你在另一个闭包中使用就必须要加这个
func loadDate(finishedCallBlock:@escaping ()->()) {
// 1. 发送异步请求
DispatchQueue.global().async {
print("发送异步请求:\(Thread.current)")
DispatchQueue.main.sync {
print("回到主线程:\(Thread.current)")
finishedCallBlock()
}
}
}
// 带参数的
func loadMoreData(success:@escaping(Dictionary<String, Any>)->()) {
DispatchQueue.global().async {
print("发送异步请求:\(Thread.current)")
DispatchQueue.main.sync {
print("回到主线程:\(Thread.current)")
success(["key":"success"])
}
}
}
// 调用方式
// loadMoreData { (response) in
// print(response)
// }
// 带参数的 jsonDate(参数名称) 参数名称前必须加 _
func loadMoreDate(finshedCallBlock:@escaping(_ jsonDate:String)->(),errorBlock:@escaping(_ error:String)->()) {
finshedCallBlock("请求成功");
errorBlock("网络异常");
}
6. <非逃逸闭包> 是指函数生命周期结束后,闭包也将被销毁,非逃逸的闭包只能在函数的内部使用,
默认都是非逃逸闭包(略)
7. <自动闭包> 自动闭包不能有参数,在调用函数传参时只能是一句表达式,闭包的返回值只能是表达式的值,闭包使用@autoclosure来申明 ()->返回值
func atuoBlockFuntion(a:Int,block:@autoclosure()->Bool) {
let valueBlock = block()
if valueBlock {
print("自动闭包z计算d值为YES")
}
}
//调用 atuoBlockFuntion(a: 10, block: 5+6>0)
网友评论