`deinit` 到底什么时候被调用? (在 Swift 中)

When is `deinit` exactly called? (in Swift)

deinit 的确切调用时间是什么时候?

当最后一个引用超出范围(通过 return、抛出或退出)时,是否保证会调用 C++

或者 Swift 使用垃圾收集器?

deinit是为了释放资源(比如释放不在ARC下的内存)。

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

什么时候调用deinit

通常,当最后一个强引用超出范围时, deinit 被立即调用(然后发生释放)。

  • 但是如果受到autorelease特性的影响, deinit会被显着延迟调用, 在最后一个引用超出范围后很久(当 autorelease 池被耗尽时)。
  • 当 App 终止时,deinit 保证永远不会被调用!? (如果尚未调用 deinit)。
  • 同样在极其常见的情况下,deinit 在强引用变量的范围结束之前被调用:
    • 在Swift中不像其他语言,当我们设置弱引用等于强引用时, 它可能导致 nil(Swift 绝对允许)。

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

    • 可能的解决方法是使用 withExtendedLifetime(_:_:) 全局方法,例如:

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

C++析构函数吗?

ObjCSwift 中没有 C++ 析构函数的等价物。

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

Swift 正在使用垃圾收集器吗?

否,但每当 autorelease 功能影响对象时, deinit 可以推迟(直到 autorelease-pool 耗尽,如上所述)。

您问的是:

When is deinit called?

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

所以,这通常不是任何特定变量的问题,而是所有引用的问题,并且在最后一个强引用被删除时被取消初始化,就在它被释放之前。请参阅 Swift 编程语言, Deinitialization and Automatic Reference Counting

你接着问:

Or is Swift using Garbage-Collector?

Swift 不使用垃圾回收。曾经有垃圾收集(早在 Objective-C 早期,针对 macOS 目标),但长期以来一直被弃用,取而代之的是引用计数系统,后来通过引入 ARC(自动引用计数)进行了简化.但是 Swift 从未实施过垃圾回收。