可选的无主引用与Swift 5.0中的弱引用

J. *_*Doe 3 automatic-ref-counting swift swift5

Swift 5.0中允许这样做:

class Person { 
    unowned var child: Person?
}
Run Code Online (Sandbox Code Playgroud)

发行说明支持此功能

无主和无主(不安全)变量现在支持可选类型。(47326769)

我完全了解Swift 4.2及以前版本中弱者和无人者的区别。但是,我不确定苹果为什么决定将unownedoptional定型。即使在文档(这是Swift 5.0的文档)中,该实现的“提案”(我还能在哪里找到旨在添加可选的未拥有引用的提案?)也没有更新,因为它说:

预计无主引用将始终具有值。因此,ARC永远不会将未拥有的引用的值设置为nil,这意味着将使用非可选类型定义未拥有的引用。

以上不再是真的。Apple声明的唯一功能差异是,unowned期望引用的寿命等于或长于持有该引用的对象。好吧,我对此的技术用途很好奇。

使用weak引用与可选 unowned引用时有什么区别?还是unowned在引用对象的生存期较长时应该使用可选的唯一区别?我希望还会有更多...

mat*_*att 7

您误解了发行说明和语言更改的含义。

苹果为何决定将无人驾驶汽车设为可选类型

他们没有。您可以而且通常会说

unowned let owner : MyViewController
Run Code Online (Sandbox Code Playgroud)

唯一的变化是,无主变量可以是Optional,以前是非法的。这项更改可解决一个烦人的边缘情况,仅此而已。

以上不再是真的

是的。事情与以前完全没有变化:

  • 弱引用必须键入为Optional;它们不保留所引用的对象,但是会跟踪所引用的对象,并nil在该对象不存在时还原为该对象。
  • 无主引用不会保留所引用的对象,也不会跟踪所引用的对象,因此由您决定防止该对象消失,否则可能会导致指针悬空和崩溃。

唯一更改的是,曾经有一个附加规则,即未拥有的引用类型不能是Optional。该规则现在消失了。

正如您正确指出的那样,如果未拥有的引用类型 Optional,则它必须是var引用,而不是let引用(因为如果您没有权力将其从nil实际更改为Optional,则将其设为Optional毫无意义。价值,反之亦然)。

一个典型的用例非常像您自己提供的:

class Node {
    unowned var parent: Node?
}
Run Code Online (Sandbox Code Playgroud)

可以合理地说,此Node可能有也可能没有父级(因为它可能位于图的顶部),但是如果它确实有父级,则该父级应该是无主的(父级应保留其子级,但孩子不应保留其父母)。以前,这样说的唯一方法是使它成为弱引用,这会带来一些不必要的开销,并且很简单,因为我们可以绝对保证,如果节点具有父级,则父级将超过子级。现在,您可以说出您的意思了,这通常是一件好事。

  • @AhmadF _you_ 的工作方式可能完全相同,但正如我在回答中所说,它会导致一些可能不需要的开销,因为您正在让运行时跟踪弱引用,以防它被解除分配。如果我们知道父级在子级的生命周期内永远不会被释放,那就是浪费时间和空间以及计算复杂性。因此,正如我在回答中所说, unowned Optional 可以让您说出您的意思并消除所有这些复杂性。 (2认同)