Swift ARC是否拥有无主引用的计数?

Swift ARC是否拥有无主引用的计数?,swift,automatic-ref-counting,strong-references,unowned-references,Swift,Automatic Ref Counting,Strong References,Unowned References,ARC保留对对象的无主引用的计数是真的吗 那么,如果一个对象的强引用计数达到0,而该对象的无主引用计数>0,那么该对象将取消初始化,但不会取消分配?只有当强引用和无主引用计数达到0时,它才会被取消分配 我在一篇文章中读到了这一点(我想是在媒体上),但我不确定这是否正确。首先,让我们知道这些问题的答案都是我们通常应该避免依赖的实现细节。现在,让我们来看看答案: ARC保留对对象的无主引用的计数是真的吗 是的,这是真的。每个对象有三个引用计数:强计数、无主计数和弱计数 始终存储强计数(但存储时调整

ARC保留对对象的无主引用的计数是真的吗

那么,如果一个对象的强引用计数达到0,而该对象的无主引用计数>0,那么该对象将取消初始化,但不会取消分配?只有当强引用和无主引用计数达到0时,它才会被取消分配


我在一篇文章中读到了这一点(我想是在媒体上),但我不确定这是否正确。

首先,让我们知道这些问题的答案都是我们通常应该避免依赖的实现细节。现在,让我们来看看答案:

ARC保留对对象的无主引用的计数是真的吗

是的,这是真的。每个对象有三个引用计数:强计数、无主计数和弱计数

  • 始终存储强计数(但存储时调整为-1,因此存储的0表示强引用计数为1,存储的1表示强引用计数为2,依此类推)

  • 无主计数也始终被存储,其调整值为+1,表示所有强引用,并在去初始化结束时被删除

  • 弱引用计数仅在创建对象的第一个弱引用后存储。弱引用计数(如果已存储)将与+1调整一起存储,该调整表示所有无主引用,并在对象解除分配后删除

那么,如果一个对象的强引用计数达到0,而该对象的无主引用计数>0,那么该对象将取消初始化,但不会取消分配

对。对象被取消初始化:对象的类和所有超类的
deinit
s被运行,对象本身作为引用的任何属性都被设置为nil。但是,对象的内存不会被释放,因为对象的头必须保持有效,直到最后一次对对象的
无主
引用被销毁

只有当强引用和无主引用计数达到0时,它才会被取消分配

对。当强引用计数和无主引用计数都达到零时,对象被解除分配。由于大多数对象从未被
无主
引用引用,因此这通常是最后一个强引用被销毁时

您没有询问弱引用,但为了完整起见,我也会解释它们。当一个对象被弱引用(或曾经被弱引用)时,Swift会为该对象分配它所称的“边表条目”(有时只是“边表”)

  • 如果对象没有边表,则强计数和无主计数直接存储在对象中,弱计数(必须为零)不存储

  • 如果一个对象有一个边表,则指向边表的指针存储在该对象中。强计数、无主计数和弱计数以及指向对象的指针存储在边表中

对对象的弱引用存储为指向边表的指针,而不是对象的指针。这意味着即使仍然存在对对象的弱引用,也可以取消分配对象(而不仅仅是取消初始化)

取消分配对象时,如果没有对该对象的弱引用,则取消分配边表。如果仍然存在弱引用,则对象将被解除分配,但边表仍保持分配状态。当销毁对解除分配对象的最后一个弱引用时,将解除分配副表

请注意,当Swift对象被取消初始化或取消分配时,弱引用不会立即设置为nil(销毁)!仅当程序尝试加载引用或弱引用的容器被反初始化时,对反初始化对象的弱引用才设置为nil。(我所说的“容器”是指,例如,当一个对象具有
弱var
属性时。该对象是
弱var
引用的容器。)


顶部的一条大评论解释了所有这些细节以及更多内容



另外还有一种参考,
无主(不安全)
,它不调整任何参考计数。如果可能的话,你应该尽量避免此类引用(而且几乎总是可以避免的)。

我建议你在问题中添加文章链接和相关摘录。但在回答您的问题时,当最后一个强引用被删除时,对象被解除分配,而不管有什么悬空的无主引用。至少,您应该链接到您所引用的文章,这样我们就可以按声明的方式处理声明,而不是您理解/表示的声明。@Rob实际上,悬而未决的引用不会保留。弱引用实际上指向“边表”中的一个条目,边表本身包含对“main”对象的引用。只要存在突出的弱引用,边表条目就会保持不变,以防止指针悬空。在使用解除分配的主对象访问弱引用时,该弱引用在边表中被取消增量,并且该特定的弱引用被取消@Alexander-这些是
弱的
参考。他询问了无主的参考资料。也许他只是记错了这篇文章,这篇文章可能是关于
weak
@Alexander-对于调试版本,你会看到这种行为,但是对于发布版本,你会看到更类似于真正的悬空指针行为。
无主
产生
无主(不安全)
优化版本的行为,例如
-Ofast
,否?在我刚才使用苹果Swift版本4.2.1(swiftlang-1000.11.42 clang-1000.11.45.1)进行的测试中,没有
-Ofast
。在
-O
-O
版本中,试图使用无效的
无主的
引用的程序报告“致命错误:试图读取