`deinit` 到底什么时候被调用? (斯威夫特)

问题描述 投票:0回答:2

deinit
到底什么时候被调用?

是否像

C++
一样,当最后一个引用超出范围(通过返回、抛出或退出)时保证被调用?

或者

Swift
使用垃圾收集器?

swift automatic-ref-counting destructor dealloc deinit
2个回答
2
投票

deinit
旨在释放资源(例如释放不在ARC下的内存)。

(感谢马丁Rob的输入,我们可以在下面得出结论)

什么时候叫
deinit

通常,当最后一个强引用超出范围时,

deinit
立即被调用(然后释放)。

但是:

  1. 如果受到
    autorelease
    功能
    (有条件)的影响,
    deinit
    会被显着延迟调用, 在最后一个引用超出范围后很久(当
    autorelease
    池耗尽时)。
  2. 或者当应用程序终止时,
    deinit
    保证永远不会被调用! (如果尚未调用
    deinit
    )。
  3. 同样在极其常见的情况下,
    deinit
    在强引用变量的作用域结束之前被调用:
    • 在 Swift 中,与其他语言不同,当我们将弱引用设置为等于强引用时, 它可能会导致

      nil
      (Swift 绝对允许)。

    • 如果编译器检测到范围的剩余行,就会发生这种情况, 没有任何强引用。

    • 可能的解决方法是使用

      withExtendedLifetime(_:_:)
      全局方法/函数,例如:

    withExtendedLifetime(myStrongRefVariable) {
        // Do something that only needs a non-nil weak reference.
    }
    

它像
C++
析构函数吗?

C++
ObjC
中没有相当于
Swift
析构函数。

Objective-C++
对象的析构函数(
dealloc
)在程序终止期间被调用, 因为这是
C++
规范所要求的, 但仅此而已,Obj-C++ 的
dealloc
行为与
deinit
相同。)

Swift 使用垃圾收集器吗?

不,但每当

autorelease
功能影响对象时,
deinit
可以推迟(直到自动释放池耗尽,如上所述)。


1
投票

你问:

什么时候叫

deinit

简而言之,对于引用类型,当最后一个强引用被删除时,对象将被取消初始化。

因此,这通常不是任何特定变量的问题,而是所有引用的问题,并且当最后一个强引用被删除时,就在它被释放之前,它被取消初始化。请参阅Swift 编程语言, 去初始化自动引用计数

你接着问:

或者 Swift 使用垃圾收集器?

Swift 不使用垃圾收集。曾经有垃圾收集(早在 Objective-C 早期,针对 macOS 目标),但它早已被弃用,并被引用计数系统取代,后来通过引入 ARC(自动引用计数)进行了简化。但 Swift 从未实现过垃圾收集。

© www.soinside.com 2019 - 2024. All rights reserved.