gpt4 book ai didi

swift - 保证局部变量中引用的生命周期

转载 作者:搜寻专家 更新时间:2023-10-31 22:04:37 25 4
gpt4 key购买 nike

Swift 中,我可以使用 ARC 机制来管理进程外部资源的生命周期,因为类的实例是可预测地取消初始化的。这与 Java 运行时等环境形成对比,在这种环境中,当垃圾收集器收集对象时实例会被取消初始化,这不能保证在定义的时间窗口内发生。

但是,当这些实例被局部变量引用时,Swift 语言和运行时对实例的生命周期做出的确切保证是什么?例如。当局部变量持有对实例的唯一引用时,最早可以释放实例的时间点是什么?

在下面的示例中,我创建了一个类的实例并将对它的引用存储在局部变量中。

public final class Something {
init() { print("something.init()") }
deinit { print("something.deinit()") }
}

func useSomething() {
let something = Something()
print("useSomething()")
}

useSomething()

在我打印 useSomething() 之后变量没有被使用,但是 deinit 在调用 print 之后 运行():

$ swift run -c release
something.init()
useSomething()
something.deinit()

似乎引用总是在变量超出范围的地方递减。将变量声明包装在 do block 中会更改顺序:

func useSomething() {
do { let something = Something() }
print("useSomething()")
}

$ swift run -c release
something.init()
something.deinit()
useSomething()

这个顺序是有保证的还是可以随着不同的编译器或优化级别而改变?


我对此感兴趣的原因是我想将 C API 包装在面向对象的 Swift API 中,并希望使用 Swift 类和引用计数自动管理使用 C API 分配的资源的生命周期。如果 C API 的每次使用都需要对其操作的资源的引用,这会非常有效,因为我知道 Swift 实例至少会存在到最后一次调用该实例所代表的资源。

但有些 API 使用全局状态来选择资源,随后对 API 的调用不需要传递对资源的引用,而是隐式地对所选资源进行操作。 OpenGL 的 glDrawElements() 隐含地使用了可能 5 或 10 个这样的资源(顶点数组、着色器、帧缓冲区、纹理……)。

最佳答案

Swift 不保证对象的生命周期直到最近的周围范围的末端,例如参见Swift 论坛中的以下主题:

在声明的地方您可以使用 withExtendedLifetime(_:_:) :

Evaluates a closure while ensuring that the given instance is not destroyed before the closure returns.

为此目的。至于道理, Dave Abrahams (Apple)状态:

The lack of such a guarantee, which is very seldom actually usefulanyhow, is what allows us to turn costly copies (with associatedrefcount traffic and, often CoW allocation and copying fallout) intomoves, which are practically free. Adopting it would basically kill ourperformance story for CoW.

Joe Groff (Apple)在同一个线程中:

Yeah, if you want to vend resources managed by an object to consumers outside of that object like this, you need to use withExtendedLifetime to keep the object alive for as long as you're using the resources. A cleaner way to model this might be to put the class or protocol in control of handling the I/O to the file handle, instead of vending the file handle itself, so that the ownership semantics fall out more naturally:

更新(2022 年 1 月):目前正在讨论是否为对象引入词法生命周期。详情见A roadmap for improving Swift performance predictability: ARC improvements and ownership control在 Swift 论坛中。

关于swift - 保证局部变量中引用的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48974241/

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