@(swift)swift
1、typealias重命名閉包api
2、swift使用閉包代替switch安全
3、尾隨閉包(閉包做爲函數參數的最後一個參數)bash
4、解決循環引用微信
5、逃逸(escaping)/非逃逸(noescape)閉包(從swift3開始,閉包默認爲非逃逸閉包)閉包
5.一、什麼是逃逸閉包?如何標記?異步
5.二、什麼狀況下使用逃逸閉包標記?async
- 5.2.一、函數外存儲
- 5.2.二、異步調用
// 有參數無返回值的
typealias closure1 = (String) ->Void
// 有參數無返回值的
typealias closure2 = (String) ->String
// 兩個參數,一個返回值
typealias closure3 = (String, String)->String
// 無參數,無返回值
typealias closure4 = ()->Void
複製代碼
typealias block = (String)->(Bool)
let shareWeChat: block = { (a) -> (Bool) in
return true
}
let shareQQ: block = { (a) -> (Bool) in
return true
}
let shareWeiBo: block = { (a) -> (Bool) in
return true
}
let map: [String: block] = ["WeChat": shareWeChat,
"WeiBo": shareWeiBo,
"QQ": shareQQ]
/* * ********** 使用 ********** */
// 若是咱們要分享到微信
if let bk: block = map["WeChat"] {
print( bk("這個視頻如此搞笑") )
}
// 若是咱們要分享到QQ
if let bk: block = map["WeiBo"] {
print( bk("這個視頻如此搞笑") )
}
// 若是咱們要分享到微博
if let bk: block = map["QQ"] {
print( bk("這個視頻如此搞笑") )
}
複製代碼
// =============================
{
func sum(by: (Int, Int) -> Int) -> Int {
return by(10, 20)
}
let num = sum() { (a, b) in
return a + b
}
print("和爲 \(num)")
}
// =============================
{
func sum1(a: Int, b: Int, by: (Int, Int) -> Int) -> Int{
return by(a, b)
}
let num1 = sum1(a: 10, b: 30) { (a, b) in
return a + b
}
print("和爲 \(num1)")
}
複製代碼
weak var weakSelf = self
,使用weakSelf調用屬性[unowned self]
[weak self]
weak
表示可用範圍內self
爲弱引用 unowned
表示可用範圍內self
都爲assign
,不會強引用,若是對象釋放,指針地址依然存在,不安全函數
做爲一個傳入參數,若該閉包在函數返回後才被執行的話,則該閉包就是在逃逸函數。(這樣的閉包就是逃逸閉包。)你須要在參數前加上@escaping標記來代表閉包是逃逸的。post
若是一個函數參數可能致使引用循環,那麼它須要被顯示地標記出來。@escaping標記能夠做爲一個警告,來提醒使用這個函數的開發者注意引用關係。
// 舉個例子。此時的callback被self所持有,典型的可能在函數return以後被執行。
class SomeClass {
var callback:(()->Void)?
func doSomething(callback:@escaping ()->Void) { // 加上逃逸修飾詞
self.callback = callback
}
}
複製代碼
同理,若是閉包被放進async dispatch queue,則該閉包也會被queue retain,一樣可能在函式結束後才被執行,所以也算是「逃逸」
// 舉個例子。此時的callback被異步調用了
class SomeClass {
func doWorkAsync(block: @escaping () -> ()) { // 加上逃逸修飾詞
DispatchQueue.main.async {
block()
}
}
}
複製代碼