取消初始化时,无主引用是否设置为“nil”?

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

我对 swift 中的这个主题感到困惑,据说无主引用必须始终有一个值并且不能是可选的,也意味着它们不能设置为“nil”....好吧,我刚刚在 Apple 上看到了一个程序Swift 的文档表明,实例“A”具有对实例“B”的无主引用,在实例“B”被取消初始化/释放后立即被取消初始化和释放……当 var 被取消初始化/释放时,这并不意味着它们设置为“nil”???实例 B 是可选的,因此确保它可以保存“nil”,但为什么实例“A”在它应该始终具有值的情况下却被取消初始化????

PS:如果这有帮助......实例“B”是一个可选类型,对实例“A”具有强引用

ios swift memory-management automatic-ref-counting dealloc
4个回答
1
投票

unowned
引用的要点是保存对您保证(基于您的应用程序逻辑)的弱引用,该弱引用不会在具有
unowned
引用的对象之前被释放。您可以在文档中阅读更多内容

从某种意义上说,它与隐式展开的可选类型类似(例如

String!
)。你告诉编译器,当它是
nil
时,你将永远不会访问该值,如果你这样做,你的程序将会崩溃。


1
投票

当对象的强引用计数降至 0 时,该对象将被取消初始化,但直到其弱引用计数也降至 0 时,该对象才会被释放。

“取消初始化”一个对象意味着如果有一个对象,则执行其

deinit
函数,释放它所拥有的任何资源,并清除它可能拥有的任何引用(可能会取消初始化和释放更多对象)。 “释放”是指内存被运行时回收。取消初始化的对象的引用计数标头仍然有效。

当您访问

weak
引用时,Swift 运行时会确保该对象仍处于初始化状态。如果不是,弱引用将设置为
nil
并且取消初始化对象的弱引用计数将减少。

无主引用也计入弱引用计数。当您访问无主引用时,Swift 运行时还会确保该对象处于初始化状态;但如果不是,它不会清除引用(它不能这样做,因为它不是可选的),而是会使您的程序崩溃。

这有效地使无主引用的行为类似于隐式解包的可选,而弱引用的行为类似于可选。

自清零弱引用和干净崩溃的无主引用的权衡是,在测试或取消初始化对象的所有弱引用之前,以及在其所有无主引用都已取消初始化之前,无法回收对象的后备内存。

来源:Swift 运行时代码


0
投票

谈论

unowned
变量在它指向的对象被释放后“保存”什么是没有意义的,因为 Swift 保证,如果你试图在它指向的对象之后访问该变量,你的应用程序将会崩溃。指向已解除分配:

另请注意,如果您尝试这样做,Swift 保证您的应用程序将崩溃 在它引用的实例之后访问无主引用 解除分配。在此你永远不会遇到意外的行为 情况。你的应用程序总是会可靠地崩溃,尽管你应该, 当然,要阻止它这样做。


0
投票

在 Swift 中,如果您使用 unowned 关键字定义对对象的引用,并且该对象在您尝试访问它之前被释放,则应用程序将崩溃。因此,仔细确定在何处使用无主引用至关重要。另一方面,如果你不确定对象是否会被释放,你可以使用weak关键字,如果对象被释放,它会自动将引用设置为nil。

总结一下:

-> 当您确定引用的对象在其整个生命周期内可用时,请使用 unowned。

-> 当你不确定引用的对象是否会被释放时,使用weak。

通过使用适当的关键字,您可以避免因访问 Swift 应用程序中已解除分配的对象而导致的崩溃。

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