`deinit` 到底什么时候被调用? (在 Swift 中)
When is `deinit` exactly called? (in Swift)
deinit
的确切调用时间是什么时候?
当最后一个引用超出范围(通过 return、抛出或退出)时,是否保证会调用 C++
?
或者 Swift
使用垃圾收集器?
deinit
是为了释放资源(比如释放不在ARC下的内存)。
(感谢Martin
和Rob的输入,我们可以在下面得出结论)
什么时候调用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++
析构函数吗?
ObjC
或 Swift
中没有 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 从未实施过垃圾回收。
deinit
的确切调用时间是什么时候?
当最后一个引用超出范围(通过 return、抛出或退出)时,是否保证会调用 C++
?
或者 Swift
使用垃圾收集器?
deinit
是为了释放资源(比如释放不在ARC下的内存)。
(感谢Martin 和Rob的输入,我们可以在下面得出结论)
什么时候调用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++
析构函数吗?
ObjC
或 Swift
中没有 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 从未实施过垃圾回收。