@(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()
}
}
}
复制代码