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

Swift中,我可以使用ARC机制来管理进程外部资源的生命周期,因为类的实例可以预先解除初始化.这与Java Runtime之类的环境形成对比,在Java Runtime中,当垃圾收集器收集对象时,实例被去初始化,这不能保证在定义的时间窗口中发生.

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

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

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

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

useSomething()

在我打印useSomething()之后不使用该变量,但是在调用print()之后deinit运行一致:

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

似乎引用总是在变量超出范围时递减.在do块中包装变量声明会更改顺序:

func useSomething() {
    do { let something = Something() }
    print("useSomething()")
}
$swift run -c release
something.init()
something.deinit()
useSomething()

这个订单是保证还是可以用不同的编译器或优化级别更改?

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

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

解决方法

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

> Should Swift apply “statement scope” for ARC
> ARC // Precise Lifetime Semantics

如果声明你可以使用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 useful
anyhow,is what allows us to turn costly copies (with associated
refcount traffic and,often CoW allocation and copying fallout) into
moves,which are practically free. Adopting it would basically kill our
performance 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:

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...