Swift   发布时间:2022-03-31  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了swift – 保证局部变量中引用的生命周期大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

在 Swift中,我可以使用ARC机制来管理进程外部资源的生命周期,因为类的实例可以预先解除初始化.这与Java Runtime之类的环境形成对比,在Java Runtime中,当垃圾收集器收集对象时,实例被去初始化,这不能保证在定义的时间窗口中发生. 但是,当局部变量引用这些实例时,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(_:_:)

为了这个目的.至于理由,
Dave Abrahams (Apple)州:

Joe Groff (Apple)在同一个帖子中:

大佬总结

以上是大佬教程为你收集整理的swift – 保证局部变量中引用的生命周期全部内容,希望文章能够帮你解决swift – 保证局部变量中引用的生命周期所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。