我了解Swift中weakunowned之间的用法和表面区别:

我所见过的最简单的示例是,如果存在DogBone,那么Bone可能对Dog的引用较弱(反之亦然),因为它们可以彼此独立存在。

另一方面,在HumanHeart的情况下,Heart可能具有对人的unowned引用,因为一旦Human被...“取消引用”,就无法再合理地访问Heart。那和CustomerCreditCard的经典示例。

因此,这不是重复询问的问题。

我的问题是,拥有两个类似的概念有什么意义?有哪些内部差异需要两个关键字来代表本质上99%的同一事物?问题是为什么存在差异,而不是差异是什么。

假设我们可以像这样设置一个变量:weak var customer: Customer!unowned变量为非可选的优点是有争议的。



...也许出于这个原因,编译器可以进行更有效的优化。

是真的,还是在幕后发生了其他事情,提供了一个令人信服的论据来保留两个关键字(尽管基于Stack Overflow流量的微小区别显然使新手和有经验的开发人员都感到困惑)。

我最感兴趣的是从Swift编译器(或其他编译器)工作的人那里听到的消息。

最佳答案



它们根本不相似。它们是一样的。

  • weak是一个非常复杂的概念,是在引入ARC时引入的。它执行了近乎奇迹般的任务,即允许您避免保留循环(通过避免使用强引用),而不必担心当引用的对象不存在时悬挂指针会导致崩溃—这在ARC之前一直存在被介绍了。
  • 另一方面,
  • unowned是非ARC弱的(具体来说,它与non-ARC assign相同)。在引入ARC之前,这是我们曾经不得不冒险的原因,它是导致如此多崩溃的原因。这是非常危险的,因为如果所引用的对象不存在,则可能会悬空指针并导致崩溃。

  • 产生这种差异的原因是,为了执行其奇迹,weak涉及到运行时的许多额外开销,这些开销由编译器插入到幕后。 weak引用是由您进行内存管理的。特别是,运行时必须维护以这种方式标记的所有引用的暂存器,并对其进行跟踪,以便如果弱引用的对象不存在,则运行时可以找到该引用并将其替换为nil以防止指针悬空。

    因此,在Swift中,weak引用始终是对Optional的引用(正是这样,因此可以将其替换为nil)。这是额外的开销来源,因为使用Optional会带来额外的工作,因为必须始终将其拆开才能完成任何工作。

    因此,在适用的地方,unowned始终是首选。但是除非绝对安全,否则请不要使用它!使用unowned,您将放弃自动内存管理和安全性。您有意恢复到ARC之前的糟糕日子。

    在我的用法中,常见的情况是在闭包需要包含self的捕获列表以避免保留周期的情况下出现的。在这种情况下,几乎总是可以在捕获列表中说出[unowned self]。当我们这样做时:
  • 对于程序员而言,它更方便,因为没有任何要解包的东西。 [weak self]是需要使用它才能进行包装的Optional。
  • 效率更高,部分原因是相同的(展开通常会增加额外的间接访问级别),部分原因是它是运行时暂存器列表要跟踪的较少的弱引用。
  • 10-06 12:58