@(swift)
一、typealias重命名闭包
二、swift使用闭包代替switch
三、尾随闭包(闭包作为函数参数的最后一个参数)
四、解决循环引用
五、逃逸(escaping)/非逃逸(noescape)闭包(从swift3开始,闭包默认为非逃逸闭包)
5.1、什么是逃逸闭包?如何标记?
5.2、什么情况下使用逃逸闭包标记?
- 5.2.1、函数外存储
- 5.2.2、异步调用
一、typealias重命名闭包
// 有参数无返回值的
typealias closure1 = (String) ->Void
// 有参数无返回值的
typealias closure2 = (String) ->String
// 两个参数,一个返回值
typealias closure3 = (String, String)->String
// 无参数,无返回值
typealias closure4 = ()->Void
复制代码
二、swift使用闭包代替switch
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)/非逃逸(noescape)闭包(从swift3开始,闭包默认为非逃逸闭包)
什么是逃逸闭包?如何标记?
作为一个传入参数,若该闭包在函数返回后才被执行的话,则该闭包就是在逃逸函数。(这样的闭包就是逃逸闭包。)你需要在参数前加上@escaping标记来表明闭包是逃逸的。
什么情况下使用逃逸闭包标记?
函数外存储
如果一个函数参数可能导致引用循环,那么它需要被显示地标记出来。@escaping标记可以作为一个警告,来提醒使用这个函数的开发者注意引用关系。
// 举个例子。此时的callback被self所持有,典型的可能在函数return之后被执行。
class SomeClass {
var callback:(()->Void)?
func doSomething(callback:@escaping ()->Void) { // 加上逃逸修饰词
self.callback = callback
}
}
复制代码
4.2、异步调用
同理,如果闭包被放进async dispatch queue,则该闭包也会被queue retain,同样可能在函式结束后才被执行,因此也算是“逃逸”
// 举个例子。此时的callback被异步调用了
class SomeClass {
func doWorkAsync(block: @escaping () -> ()) { // 加上逃逸修饰词
DispatchQueue.main.async {
block()
}
}
}
复制代码