gpt4 book ai didi

ios - 闭包如何在 Swift 中捕获值?

转载 作者:行者123 更新时间:2023-12-04 13:07:32 26 4
gpt4 key购买 nike

我正在运行以下代码 -

class Element {
var name: String

init(name: String) {
self.name = name
}

deinit {
print("Element is deinitializing...")
}
}

var element: Element? = Element(name: "Silver")

var closure = {
print(element?.name ?? "default value")
}

print(isKnownUniquelyReferenced(&element))
element?.name = "Gold"
element = nil
closure()
它打印 -
true
Element is deinitializing...
default value
在上面,不是闭包捕获 element强烈? element怎么了在 closure 中变为零?

最佳答案

来自 Swift Programming Guide - Closures

A closure can capture constants and variables from the surrounding context in which it’s defined. The closure can then refer to and modify the values of those constants and variables from within its body, even if the original scope that defined the constants and variables no longer exists.


闭包捕获变量,而不是变量的内容。当我们谈论函数中的局部变量(通常在堆栈上分配)时,它确保即使在函数退出并且其他局部变量被释放时它们也可以访问,因此我们可以这样做:
func myFunc() {
var array: [Int] = []

DispatchQueue.main.async {
// executed when myFunc has already returned!
array.append(10)
}
}
你的例子很相似。闭包捕获变量。这是模块级别的变量,因此其作用域始终存在。当您重新分配它的值时,它将影响在闭包内读取的值。
或者,换句话说,闭包将等价于:
var closure = {
print(CurrentModule.element?.name ?? "default value")
}
哪里 CurrentModule是主模块的名称(通常是项目的名称)。
为了防止这种行为并捕获变量的值,我们可以使用闭包捕获列表。不幸的是,官方文档没有正确解释捕获列表到底是什么。基本上,使用捕获列表,您可以使用创建闭包时可用的值来声明闭包本地的变量。
例如:
var closure = { [capturedElement = element] in
print(capturedElement?.name ?? "default value")
}
这将创建一个新变量 capturedElement在闭包内部,具有变量 element 的当前值.
当然,通常我们只写:
var closure = { [element] in
print(element?.name ?? "default value")
}
这是 [element = element] 的简写.

关于ios - 闭包如何在 Swift 中捕获值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68695701/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com