iOS Swift 里的捕获变量

在 Swift 中,闭包不仅可以作为函数的简洁表达方式,还能捕获和存储其所在上下文中的常量和变量。捕获的变量会随着闭包的生命周期延续,即使这些变量已经超出了原作用域,它们仍然可以在闭包中被访问和修改。这种行为被称为闭包捕获,是闭包的核心特性之一。

//变量值捕获

func makeIncrementer() -> () -> Int {
    var total = 0  // 这是外部变量
    let incrementer: () -> Int = {
        total += 1  // 闭包捕获了外部变量 total
        return total
    }
    return incrementer
}

let increment = makeIncrementer()
print(increment())  // 输出 1
print(increment())  // 输出 2
// 在这个例子中,total 变量是在 makeIncrementer 函数内定义的,它对 incrementer 闭包来说是“外部”的。但由于闭包捕获了这个外部变量,total 可以在闭包内部被修改和访问。

 

//引用类型捕获

class ReferenceType {
    var value: Int = 0
}
func referenceClosure() -> () -> Int {
    let ref = ReferenceType()//函数内声明了一个局部变量 
    let closure: () -> Int = {
        ref.value += 1 //闭包内修改外界变量
        return ref.value
    }
    return closure
}

let closureRef = referenceClosure()
print(closureRef()) // 输出 1
print(closureRef()) // 输出 2
//closure 是一个闭包,它捕获了 ReferenceType 的实例 ref。这个 ref 是 referenceClosure 函数中的局部变量,但由于被闭包捕获,在 referenceClosure 返回后,ref 仍然存在于闭包中,并且它的 value 属性可以继续被修改。

 

为什么闭包要捕获外部变量?

闭包需要捕获外部变量,主要是为了保持它们的状态,即使闭包所在的作用域已经结束。

 

  • 如果一个变量定义在函数内部,但闭包捕获了它,该变量就不会随着函数的结束而销毁。闭包可以长期持有该变量的引用,并在后续调用时继续使用它。
  • 闭包内部变量:是在闭包的代码块内部定义并使用的变量,通常只能在闭包内访问。
  • 外部变量:是在闭包所在的作用域(函数或其他代码块)中定义,但被闭包引用的变量。由于它们是在闭包外部定义的,所以称为“外部变量”。

posted on 2024-10-17 15:49  ACM_Someone like you  阅读(9)  评论(0编辑  收藏  举报

导航