正文
/* 7:闭包
1: ** 闭包能够捕获和存储定义在其上下文中的 任何常量和变量的引用,
这也就是所谓的闭合并包裹那些常量和变量,因此被称为“闭包”.
Swift 能够为你处理所有关于捕获的内存管理的操作。
2: 闭包的好处
利用上下文推断形式参数和返回值的类型;
单表达式的闭包可以隐式返回;
简写实际参数名;
尾随闭包语法。
3:*** 闭包表达式
1:闭包表达式语法有如下的一般形式:
{ (parameters) -> (return type) in
statements
}
总之对于行内闭包表达式来说,形式参数类型和返回类型都应写在花括号内而不是花括号外面。
闭包的函数整体部分由关键字 in 导入,这个关键字表示闭包的形式参数类型和返回类型定义已经完成,并且闭包的函数体即将开始。
2:从语境中推断类型
3: 从单表达式闭包隐式返回
4: 简写的实际参数名
5: 运算符函数
6: 尾随闭包
如果你需要将一个很长的闭包表达式作为函数最后一个实际参数传递给函数且闭包表达式很长,使用尾随闭包将增强函数的可读性。尾随闭包是一个被书写在函数形式参数的括号外面(后面)的闭包表达式,但它仍然是这个函数的实际参数
7: 捕获值
8: 逃逸闭包和自动闭包 @autoclosure 和 @escaping 标志
*/
import UIKit
class SevenBlockVC: UIViewController {
public var editCompleteSuccessBlock: (String) -> () = {_ in } // 编辑完成点击事件的回调
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
self.title = "7:闭包"
// 8: 如果你想要捕获 self ,就明显地写出来,或者在闭包的捕获列表中包含 self 。显式地写出 self 能让你更清楚地表达自己的意图,并且提醒你去确认这里有没有引用循环
editCompleteSuccessBlock = { [weak self] str in
guard let self = self else { return }
self.title = str
}
editCompleteSuccessBlock("7:闭包1")
// 1:in关键字
blockTestIn()
blockTestIn1()
blockTestIn2()
blockTestIn3()
blockTestIn4()
// 尾随闭包
loadPicture(from: 1) { _ in
} onFailure: { _ in
}
}
/* 1: in 关键字
闭包的函数整体部分由关键字 in 导入,这个关键字表示闭包的形式参数类型和返回类型定义已经完成,并且闭包的函数体即将开始。
*/
private func blockTestIn() {
let names = ["Chris","Alex","Ewa","Barry","Daniella"]
let reversedNames1 = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
print(reversedNames1);
}
// 2: 闭包 简写 从语境中推断类型
private func blockTestIn1() {
let names = ["Chris","Alex","Ewa","Barry","Daniella"]
let reversedNames = names.sorted(by: { (s1, s2) -> Bool in
return s1 > s2
})
print("闭包隐式返回:\(reversedNames)");
}
// 3: 闭包 简写 从单表达式闭包隐式返回
private func blockTestIn2() {
let names = ["Chris","Alex","Ewa","Barry","Daniella"]
let reversedNames = names.sorted(by: { (s1, s2) in
s1 > s2
})
print("闭包隐式返回:\(reversedNames)");
}
// 4: 闭包 简写 简写的实际参数名 Swift 自动对行内闭包提供简写实际参数名,你也可以通过 $0 , $1 , $2 等名字来引用闭包的实际参数值。
private func blockTestIn3() {
let names = ["Chris","Alex","Ewa","Barry","Daniella"]
let reversedNames = names.sorted(by: { $0 > $1 } )
print("简写的实际参数名:\(reversedNames)");
}
// 5: 闭包简写 运算符函数
private func blockTestIn4() {
let names = ["Chris","Alex","Ewa","Barry","Daniella"]
let reversedNames = names.sorted(by: > )
print("运算符函数:\(reversedNames)");
}
/* 6:**** 尾随闭包
如果你需要将一个很长的闭包表达式作为函数最后一个实际参数传递给函数且闭包表达式很长,使用尾随闭包将增强函数的可读性。尾随闭包是一个被书写在函数形式参数的括号外面(后面)的闭包表达式,但它仍然是这个函数的实际参数。当你使用尾随闭包表达式时,不需要把第一个尾随闭包写对应的实际参数标签。函数调用可包含多个尾随闭包,
如果函数接收多个闭包,你可省略第一个尾随闭包的实际参数标签,但要给后续的尾随闭包写标签。比如说,下面的函数给照片墙加载图片:
*/
func loadPicture(from server: Int, completion: (Int) -> Void, onFailure: (Int) -> Void) {
if server == 0 {
completion(1)
} else {
onFailure(0)
}
}
}