【问题标题】:Optional unowned reference versus weak in Swift 5.0Swift 5.0 中可选的无主引用与弱引用
【发布时间】:2019-07-18 01:41:26
【问题描述】:

这在 Swift 5.0 中是允许的:

class Person { 
    unowned var child: Person?
}

this release notes 支持:

unowned 和 unowned(unsafe) 变量现在支持可选类型。 (47326769)

在 Swift 4.2 及之前版本中,我完全理解了 weak 和 unowned 之间的区别。但是,我不确定为什么 Apple 决定将 unowned 设为 optional 类型。即使在docs(Swift 5.0 的文档)中,这个实现的“提案”(我什至在哪里可以找到带有添加可选无主引用的动机的提案?)也没有更新,因为它说:

一个无主的引用应该总是有一个值。因此, ARC 从不将无主引用的值设置为 nil,这意味着 无主引用是使用非可选类型定义的。

以上不再正确。 Apple 声明的唯一功能差异是 unowned 引用的生命周期应与持有该引用的对象相同或更长。好吧,我很好奇它的技术用途。

当我使用 weak 参考与 可选 unowned 参考时有什么区别?或者,当引用对象的生命周期较长时,应该使用可选的unowned 的唯一区别是什么?我希望必须有更多...

【问题讨论】:

    标签: swift automatic-ref-counting swift5


    【解决方案1】:

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

    为什么 Apple 决定将 unowned 设为可选类型

    他们没有。你可以而且通常仍然会说

    unowned let owner : MyViewController
    

    这里唯一的变化是无主变量可以是一个Optional,这在以前是非法的。这种变化解决了一个恼人的边缘情况,仅此而已。

    以上不再正确

    是的,是的。和以前完全没有变化:

    • 弱引用必须输入为可选;他们不保留引用的对象,但他们跟踪引用的对象,如果该对象不存在,则恢复为nil
    • 无主引用不保留所引用的对象,也不跟踪所引用的对象,因此由您决定防止该对象消失,否则您最终可能会出现悬空指针和崩溃。李>

    唯一改变的是以前有一个附加规则,即无主引用类型不能是可选的。这条规则现在已经不复存在了。

    正如您正确指出的那样,如果无主引用类型 一个 Optional,这必须是一个 var 引用,而不是一个 let 引用(因为这是一个 Optional 将不会如果您没有能力将其从 nil 更改为实际值,反之亦然)。

    典型的用例与您自己提供的非常相似:

    class Node {
        unowned var parent: Node?
    }
    

    说这个节点可能有也可能没有父节点似乎是合理的(因为它可能位于图表的顶部),但是如果它确实有一个父节点,那么该父节点应该是无主的(父母应该保留它的孩子,但孩子不应该保留它的父母)。以前,唯一的说法是使它成为一个弱引用,这会带来一些不必要的开销,而且是不恰当的,因为我们可以绝对保证,如果一个节点有父节点,则父节点的寿命会比子节点长。现在,你可以说出你的意思了,这通常是一件好事。

    【讨论】:

    • 因此,例如我的解释 apeth.com/swiftBook/ch05.html#_weak_referencesapeth.com/swiftBook/ch05.html#_unowned_references 中的所有内容都是正确的,除了“事实上,它 [一个无主的引用] 不能 是可选”应该被删除。
    • 是否有任何理由必须将可选的无主引用标记为“var”?为什么不允许?尝试执行此操作时会出现以下错误:''unowned' 必须是可变变量,因为它可能会在运行时更改'。我不知道为什么会这样,因为通常一个非可选的 unowned let 也可能是 nil (这有点表示编程错误,但除此之外)。
    • "因为通常一个非可选的 unowned let 可能是 nil" 这些是非常奇怪的词。你能再解释一下吗?在 Swift 中,only 可以ever 成为nil 的东西是可选的;这就是 nil 的含义,即它是 Optional 的可能值。那你怎么能把“non-optional”和“nil”放在这样的句子里呢?
    • 当我将一个对象标记为let unowned 时,该对象可能为零(对象已被释放)。这意味着我得到了一个let unowned 引用,它有一个非可选类型,它指向任何东西(nil)。这表明对该对象的引用实际上是可变的,对吗?它将对对象的引用更改为空。我定义了一个对对象的非可选引用,该对象实际上以后可以指向任何内容。这就是为什么我很困惑我需要将可选的unowned 引用标记为var,因为即使使用unowned let,引用已经是可变的。
    • @AhmadF 它可能对 you 的工作方式完全相同,但正如我在回答中所说,它会导致一些可能不需要的开销,因为你正在让运行时保持跟踪弱引用以防它被释放。如果我们知道父级在子级的生命周期内永远不会被释放,那就是浪费时间和空间以及计算复杂性。因此,正如我在回答中所说,unowned Optional 可以让您说出您的意思并消除所有这些复杂性。
    猜你喜欢
    • 2017-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    • 2020-02-26
    相关资源
    最近更新 更多