闭包是一个在上下文中闭合的独立的函数代码块,可以在代码中被传递和使用。swift中的闭包与OC中的block相似,并且更强大,可以作为参数传递给函数。
语法
{(parameters) -> return type in
code
}
- parameters:请求参数
- return type: 返回值类型
- in:分割返回值类型和代码块的关键字
- code:代码块
闭包的简化
1.没有请求参数的闭包,可以省略in
let closure1 = {()
print("hh")
}
2.没有请求参数的闭包,可以省略()
,同时必须省略in
let closure1 = {
print("hh")
}
3.闭包内表达式只有一行,可以省略return
let closure4 = {(a: Int, b: Int) in
a+b
}
4.使用简化参数名,
1(从0开始,表示第i个参数...)
let numArr = [5, 1, 4, 2, 7]
let newArr = numArr.sorted(by: {$0 > $1})
print(newArr)
5.闭包作为函数最后一个参数(尾随闭包),将闭包写在()
后
定义函数:
func getString(str1: String, str2: String, closure:(String, String) -> String) -> String {
return closure(str1, str2)
}
省略前:
let appendStrClosure = { (str1: String, str2: String) in
return str1 + str2
}
let newStr = getString(str1: "字符串1", str2: "字符串2", closure: appendStrClosure)
print("函数执行结果:", newStr)
省略为
let newStr1_1 = getString(str1: "字符串1", str2: "字符串2") {
return $0 + $1
}
6. 闭包作为函数的唯一参数,可以省略()
定义函数:
func closureFunc(closure: () -> Void) -> Void {
closure()
}
调用函数:
closureFunc {
print("closure执行完毕")
}
特点:
- 值捕获:
闭包可以在其被定义的上下文中捕获常量或变量。即使定义这些常量和变量的原作用域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。 - 引用类型:
将函数或闭包赋值给一个常量或者变量,实际上都是将常量或变量的值设置为对应函数或闭包的引用
闭包的类型
1.无参 无返回值
-
声明
let closure1 = {
print("hh")
}
-
调用
closure1()
2.无参 有返回值
-
声明
let closure2 = {
return "哈哈"
}
-
调用
print(closure2())
3.有参 无返回值
-
声明
let closure3 = {(a: String) in
print(a)
}
-
调用
closure3("zz")
4.有参 有返回值
-
声明
let closure4 = {(a: Int, b: Int) in
return a+b
}
-
调用
print(closure4(1, 2))
特殊的闭包
1.尾随闭包
闭包作为函数的最后一个参数,函数调用的时候可以将闭包写在()
后面,称为尾随闭包
-
函数声明
func getString(str1: String, str2: String, closure:(String, String) -> String) -> String {
return closure(str1, str2)
}
-
函数调用
let newStr1_1 = getString(str1: "字符串1", str2: "字符串2") {
return $0 + $1
}
2.逃逸闭包
当闭包作为一个参数传递给一个函数,并能在函数执行结束后调用,就说这个闭包逃逸了。
声明函数时,闭包的形参前用@escaping
修饰,来表示这是一个逃逸闭包,对开发者也是一个警示作用。
- 函数声明:
var result: ()->Void = {}
var string = ""
func showFunc(closure: @escaping () -> Void) {
result = closure//2
}
- 函数调用:
showFunc {self.string = "逃逸闭包"}//1
print(string)//3
result()//4
print(string)//5
- 分步理解:
- 调用函数,传入一个闭包;
- 函数内,将传入的闭包赋给result后,函数执行结束;
- 打印字符串,此时闭包还没调用;
- 调用result闭包;
- 调用result后再次打印,此时闭包才调用。
页面间传值
- 用
typealias
为闭包类型起别名 - 声明一个变量,类型为别名。
typealias voidClosure = (String) -> Void
var closure : voidClosure?
- 在触发传值的位置调用闭包
if closure != nil {
self.closure!("Did Add")
self.navigationController?.popViewController(animated: true)
}
- 在上级页面,实现闭包
vc.closure = { string in
print(string)
}
网友评论