前提:
swift
語法很惡心,其中閉包占一半婴洼。沒有oc
語法那么直觀嚴(yán)謹(jǐn)骨坑,太靈活也不好,有點(diǎn)類似弱語言窃蹋,很多東西很隨意卡啰,但是對于有無值和類型,卻又控制的很死警没。
一:閉包的基本幾種常見格式:
MARK1: 無參 無返回
let driving1 = {
print("我要去開車2")
}
MARK2: 有參 無返回
let driving3 = { (place: String) in
print("我要去開車3" + place)
}
driving3("xxxx")
MARK3: 有參 有返回
let driving4 = { (place: String) -> String in
return "我要去開車4" + place
}
let message = driving4("哈哈哈哈")
print(message)
二:閉包的其他幾種常見格式:
MARK: 第1種寫法
//let append = {(str1 aa:String,Str2 bb: String)-> String in 報(bào)錯(cuò)匈辱,閉包沒有外部參數(shù)名
let append1 = {(str1:String, Str2:String) -> String in
return "\(str1)\(Str2)"http://2030
}
//print(append(str1:"20",str2:"30")) 報(bào)錯(cuò)沧竟,閉包里面不用傳參數(shù)名
print(append1("20","30"))//2030
MARK: 第2種寫法
//以上等價(jià)于
let append2: (String, String) -> String = {
(str1, str2) in
return str1 + str2
}
print(append2("one", "two"))//onetwo
MARK: 重命名 示例
typealias append3 = (String) -> Void
func getXySuFangFa(result:append3){
result("好人一生平安")
}
print(getXySuFangFa(result: { (String) in
print("\(String)")//輸出:好人一生平安
}))
MARK: 閉包的創(chuàng)建断楷、賦值、調(diào)用
//方式一:利用typealias最完整的創(chuàng)建
typealias addBlock = (_ num1: Int, _ num2: Int) -> (Int)
//創(chuàng)建一個(gè) addBlock 類型的閉包常量:addCloser1
let addCloser1: addBlock
//為已經(jīng)創(chuàng)建好的常量 addCloser1 賦值
addCloser1 = {
(_ num1: Int, _ num2: Int) -> (Int) in
return num1 + num2
}
//調(diào)用閉包并接受返回值
let result1 = addCloser1(20, 10)
print(result1)
形式二:閉包類型申明和變量的創(chuàng)建合并在一起
let addCloser2: (_ num1: Int, _ num2: Int) -> (Int)
//為已經(jīng)創(chuàng)建好的常量 addCloser2 賦值
addCloser2 = {
(_ num1: Int, _ num2: Int) -> (Int) in
return num1 + num2
}
//調(diào)用閉包并接受返回值
let result2 = addCloser2(20, 10)
print(result2)
形式三:省略閉包接收的形參亿扁、省略閉包體中返回值
let addCloser3: (Int, Int) -> (Int)
addCloser3 = {
(num1, num2) in
return num1 + num2
}
//調(diào)用閉包并接受返回值
let result3 = addCloser3(20, 10)
print(result3)
形式四:在形式三的基礎(chǔ)上進(jìn)一步精簡
let addCloser4: (Int, Int) -> (Int) = {
(num1, num2) in
return num1 + num2
}
//調(diào)用閉包并接受返回值
let result4 = addCloser4(20, 10)
print(result4)
形式五:如果閉包沒有接收參數(shù)省略in
let addCloser5: () -> (String) = {
return "這個(gè)閉包沒有參數(shù)树酪,但是有返回值"
}
//調(diào)用閉包并接受返回值
let result5 = addCloser5()
print(result5)
形式六:簡寫的實(shí)際參數(shù)名
let addCloser6: (String, String) -> (String) = {
return "閉包的返回值是:\($0),\($1)"
}
//調(diào)用閉包并接受返回值
let result6 = addCloser6("Hello", "Swift!")
print(result6)
三:閉包的幾種用法:
MARK:1 使用sort方法和閉包進(jìn)行數(shù)組排序
/*
sort方法返回一個(gè)數(shù)組的有序版本浅碾。
(sort方法即為Swift2.0之前的sorted方法。而原來的sort方法改名為sortInPlace续语,用來將原數(shù)組修改成有序版本)
*/
func fnagfa1() {
var numbers = [12,25,1,35,27]
let numbersSorted: () = numbers.sort(by: { (n1: Int, n2: Int) -> Bool in
//進(jìn)行從小到大的排序
return n2 > n1
})
print(numbersSorted) //[1, 12, 25, 27, 35]
}
MARK:2 閉包可以不用指定參數(shù)類型垂谢,編譯器會幫我們推斷的
func fnagfa2() {
var numbers = [12,25,1,35,27]
let numbersSorted: () = numbers.sort(by: { n1, n2 in
//進(jìn)行從小到大的排序
return n2 > n1
})
print(numbersSorted) //[1, 12, 25, 27, 35]
}
MARK:3 還可以省略參數(shù)名,直接根據(jù)數(shù)字來引用每個(gè)參數(shù)(1滥朱,$2......)
func fnagfa3() {
var numbers = [12,25,1,35,27]
let numbersSorted: () = numbers.sort(by: {
//進(jìn)行從小到大的排序
return $1 > $0
})
print(numbersSorted) //[1, 12, 25, 27, 35]
}
MARK:4 如果閉包只包含一行代碼,可以省略return關(guān)鍵字
func fnagfa4() {
var numbers = [12,25,1,35,27]
let numbersSorted: () = numbers.sort(by: {
//進(jìn)行從小到大的排序
$1 > $0
})
print(numbersSorted) //[1, 12, 25, 27, 35]
}
MARK:5 如果一個(gè)閉包是函數(shù)調(diào)用的最后一個(gè)參數(shù)力试,可以將它放在括號外面徙邻。提高可讀性。
func fnagfa5() {
var numbers = [12,25,1,35,27]
let numbersSorted: () = numbers.sort(){
//進(jìn)行從小到大的排序
$1 > $0
}
print(numbersSorted) //[1, 12, 25, 27, 35]
}
MARK:6 這個(gè)換行也是可選的畸裳,所以代碼可再次精簡
func fnagfa6() {
var numbers = [12,25,1,35,27]
let _: () = numbers.sort(){
$1 > $0
}
}
MARK:7 閉包也可以存儲在變量中缰犁,像調(diào)用函數(shù)一樣調(diào)用它們
func fnagfa7() {
let comparator = {(a: Int, b: Int) in
a < b
}
let _ :Bool = comparator(5,2) //false
let _ :Bool = comparator(2,5) //true
}
四:閉包傳值:
在ViewController3.m
里面點(diǎn)擊按鈕,跳轉(zhuǎn)到ViewController4.m
怖糊,在ViewController4.m
返回的時(shí)候?qū)⒅祩鬟f到ViewController3.m
里面帅容。
ViewController3.m
里面
import UIKit
class ViewController3: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
let btn = UIButton.init(frame: CGRect(x: 50, y: 145, width: 275, height: 44))
self.view.addSubview(btn)
btn.backgroundColor = UIColor.systemTeal
btn.setTitle("點(diǎn)擊我閉包傳值", for: UIControl.State.normal)
btn.addTarget(self, action: #selector(click), for: UIControl.Event.touchUpInside)
}
@objc func click() {
let vc = ViewController4.init()
vc.block = { (str1:String,str2:String) -> String in
print("閉包傳遞的值為str1: \(str1) str2:\(str2) ")
return str1
}
self.navigationController?.pushViewController(vc, animated: true)
}
}
ViewController4.m
里面
import UIKit
class ViewController4: UIViewController {
var block = {(str1:String,str2:String) -> String in
return str1 + str2
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.block("毛阿莫","狗狗")
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
}
}
其他:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
getData { (data) in
print("閉包結(jié)果返回--\(data)--\(Thread.current)")
}
}
func getData(closure:@escaping (Any) -> Void) {
print("函數(shù)開始執(zhí)行--\(Thread.current)")
DispatchQueue.global().async {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+2, execute: {
print("執(zhí)行了閉包---\(Thread.current)")
closure("345")
})
}
print("函數(shù)執(zhí)行結(jié)束---\(Thread.current)")
}
}