What good are unowned references?

时间:2016-12-09 13:06:44

标签: swift

Weak and Unowned references are used to prevent retain cycles in the situation where two objects each hold a reference to the other. I get the use of weak but I do not get the use of unowned. Here is Apple's example of a situation where one of the two objects should use an unowned reference:

class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) { self.name = name }
}

class CreditCard {
     let number: UInt64
     unowned let customer: Customer
     init(number: UInt64, customer: Customer) {
         self.number = number
         self.customer = customer
     }
}

The idea is that a credit card cannot exist without a customer. Therefore a credit card can dispense with the optional unwrapping that the use of a weak reference would entail, and can instead use an unowned reference. Hmmm ... so why not use a strong reference? If all other references to the customer were to go away (which is not supposed to happen?) then the credit card's use of an owned reference would result in a crash; whereas its use of a strong reference would result in a memory leak. Huh? A choice between two evils? Better to crash because that is more likely to be noticed during development and testing?

Please help with some insight. Thanks.

6 个答案:

答案 0 :(得分:4)

  

最好崩溃,因为在开发和测试过程中更容易被注意到?

是。

嗯,不完全是。

我们的想法是,您应用的设计应该确保没有CreditCard实例超过它的相应Customer实例。当您使用unowned您相信自己时,可以在设计中使用逻辑上保证无崩溃执行。

现在,为什么有人会使用unowned而不是weak?简单! unowned消除了Optional展开的整个麻烦,如果您知道您的CreditCard实例将永远不会超过相应的Customer实例,那么您应该一定使用unowned

答案 1 :(得分:3)

unowned实际上比weak好得多,在适当的情况下(即确定无主对象不会不存在),因为:

  • 弱引用必须是可选的,可能需要展开,

  • 弱引用需要大量开销才能跟踪引用,如果它被解除分配则将其更改为nil,而无主引用需要零开销。

答案 2 :(得分:1)

实际上这不是一个问题,因为就目前而言,unowned引用不会创建任何类型的强引用循环。取消分配Customer对象后,其CreditCard也将立即解除分配。您的CreditCard永远不会有机会引用已解除分配的Customer

答案 3 :(得分:0)

非常有趣的问题。根据{{​​3}}

,Weak和Unowned References之间存在一些差异
  

弱参考

弱引用是一种引用,它不会强制保留它引用的实例,因此不会阻止ARC处理引用的实例。此行为会阻止引用成为强引用循环的一部分。

  

无主参考

与弱引用类似,无主引用不会强制保留它引用的实例。但是,与弱引用不同,当另一个实例具有相同的生命周期或更长的生命周期时,将使用无主引用。

  

您的问题的答案:

weak可以变为零,而unowned被假定为永不变为零,因此weak将是可选的,因为unowned不需要是可选的。

在这种情况下,Customer可能有CreditCard,也可能没有CreditCard,但Customer不存在display:none;

答案 4 :(得分:-1)

好的,我终于明白了:

  1. 对客户的最后一次引用(信用卡除外)设置为nil。
  2. ARC检查客户的引用计数:
  3. 信用卡有很强的参考价值 - 客户的参考计数为1,因此ARC不会解除分配。结果 - 内存泄漏。
  4. 或者,信用卡有一个无主参考 - 客户的参考计数为0,因此ARC将解除分配。这样做会导致信用卡的引用计数变为0,从而导致其被解除分配。因此,信用卡永远不会有机会取消其现在的无主要参考。结果 - 没有崩溃。
  5. 因此,如果我们设计了我们的代码,以便在引用的对象(Customer)被释放时保证引用的持有者(CreditCard)被解除分配,那么我们就有了这样的场景,因此设计了无主引用。

    谢谢@Bob

答案 5 :(得分:-2)

快速搜索此主题,可以将this链接到另一个SO答案。

基本上weak引用可以是nil,也可以不是unowned,而nil引用假定它永远不会是unowned

您可以在Apple docs中了解有关它们的更多信息。

我猜测在这种情况下使用unowned背后的原因完全是因为假定nil永远不会是size_repl(没有客户)。