聊一聊Swift中的闭包

语言: CN / TW / HK

我正在参加「掘金·启航计划」

Swift中的闭包Closure.

1 Swift中的闭包结构是什么样的?

{ (参数列表) -> 返回值类型 in 函数体代码 }

2 什么是尾随闭包?

  • 将一个很长的闭包表达式作为函数的最后一个实参.
  • 使用尾随闭包可以增强函数的可读性.
  • 尾随闭包是一个被书写在函数调用括号外面(后面)的闭包表达式. ``` // fn就是一个尾随闭包参数 func exec(v1: Int, v2: Int, fn: (Int, Int) -> Int) { print(fn(v1, v2)) }

// 调用 exec(v1: 10, v2: 20) { $0 + $1 } ```

image.png

3 什么是逃逸闭包?

  • 当闭包作为一个实际参数传递给一个函数或者变量的时候, 我们就说这个闭包逃逸了, 可以在形式参数前写@escaping来明确闭包是允许逃逸的.
  • 非逃逸闭包、逃逸闭包, 一般都是当做参数传递给函数.
  • 非逃逸闭包: 闭包调用发生在函数结束前, 闭包调用在函数作用域内.
  • 逃逸闭包: 闭包有可能在函数结束后调用, 闭包调用逃逸出了函数的作用域, 需要通过 @escaping声明. ``` // 定义一个数组用于存储闭包类型 var completionHandlers: [() -> Void] = []

// 在方法中将闭包当做实际参数, 存储到外部变量中 func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) { completionHandlers.append(completionHandler) } `` - **上面这种情况, 如果不标记函数的形式参数为escaping`, 就会编译报错.**

4 什么是自动闭包?

  • 自动闭包是一种自动创建的用来把作为实际参数传递给函数的表达式打包的闭包.
  • 它不接受任何实际参数, 并且当它被调用时, 它会返回内部打包的表达式的值.
  • 这个语法的好处在于通过写普通表达式代替显式闭包而使你省略包围函数形式参数的括号. func getFirstPositive(_ v1: Int, _ v2: @autoclosure () -> Int) -> Int? { return v1 > 0 ? v1 : v2() } getFirstPositive(10, 20)
  • 为了避免与期望冲突, 使用了@autoclosure的地方最好明确注释清楚: 这个值会被推迟执行.
  • @autoclosure会自动将20封装成闭包{ 20 }
  • @autoclosure只支持()->T格式的参数
  • @autoclosure并非只支持最后一个参数
  • @autoclosure、无@autoclosure, 构成了函数重载.

发文不易, 喜欢点赞的人更有好运气👍 :), 定期更新+关注不迷路~

ps:欢迎加入笔者18年建立的研究iOS审核及前沿技术的三千人扣群:662339934,坑位有限,备注“掘金网友”可被群管通过~