乐闻世界logo
搜索文章和话题

Swift 中的闭包是什么?什么是逃逸闭包和非逃逸闭包?

2月21日 15:10

Swift 中的闭包是什么?闭包的捕获列表是什么?什么是逃逸闭包和非逃逸闭包?

Swift 中的闭包是自包含的函数代码块,可以在代码中被传递和使用。闭包可以捕获和存储其所在上下文中任意常量和变量的引用。

闭包的基本概念:

  • 闭包是引用类型
  • 可以作为参数传递给函数
  • 可以作为函数的返回值
  • 可以存储在变量或常量中
  • 三种形式:全局函数、嵌套函数、闭包表达式

闭包的语法:

swift
// 完整形式 let greeting = { (name: String) -> String in return "Hello, \(name)" } // 简化形式 let greeting = { name in "Hello, \(name)" } // 最简形式(使用参数缩写) let greeting: (String) -> String = { "Hello, \($0)" }

捕获列表:

  • 用于显式声明闭包要捕获的变量
  • 使用 [weak self][unowned self] 避免循环引用
  • 使用 [weak var = weakVar] 捕获弱引用
  • 使用 [unowned var = var] 捕获无主引用
  • 示例:
    swift
    let closure = { [weak self] in self?.doSomething() }

逃逸闭包:

  • 在函数返回后仍会被调用的闭包
  • 使用 @escaping 标记
  • 必须显式引用 self
  • 常用于异步操作、回调、网络请求
  • 示例:
    swift
    func request(completion: @escaping (Result) -> Void) { DispatchQueue.global().async { let result = fetchData() completion(result) } }

非逃逸闭包:

  • 在函数返回前会被调用的闭包
  • Swift 3.0+ 默认为非逃逸
  • 可以隐式引用 self
  • 性能更好,编译器可以优化
  • 示例:
    swift
    func process(_ closure: (Int) -> Void) { closure(42) }

最佳实践:

  1. 使用捕获列表避免循环引用
  2. 优先使用非逃逸闭包
  3. 合理使用尾随闭包语法
  4. 使用 weakunowned 处理 self 引用
  5. 考虑闭包的内存开销
标签:Swift