小编典典

弱引用和无主引用有什么区别?

all

斯威夫特有:

  • 强引用
  • 弱引用
  • 无主引用

无主引用与弱引用有何不同?

什么时候使用无主引用是安全的?

无主引用是否存在安全风险,例如C/C++ 中的悬空指针?


阅读 147

收藏
2022-05-16

共1个答案

小编典典

weak和引用都unowned不会在被引用对象上创建strong保留(也就是它们不会增加保留计数以防止 ARC 释放被引用对象)。

但是为什么有两个关键字呢?这种区别与OptionalSwift
语言中内置的类型有关。长话短说:可选类型提供内存安全(这与Swift
的构造函数规则
完美配合——为了提供这种好处,这些规则非常严格)。

weak引用允许它成为可能(这在nil被引用的对象被释放时自动发生),因此您的属性类型必须是可选的 -
所以作为程序员,您有义务在使用它之前检查它(基本上是编译器尽可能地强迫你编写安全代码)。

unowned参考假定它在其生命周期内永远不会变成nil。必须在初始化期间设置无主引用——这意味着该引用将被定义为非可选类型,无需检查即可安全使用。如果以某种方式被引用的对象被释放,那么当使用无主引用时应用程序将崩溃。

来自苹果文档

只要该引用在其生命周期中的某个时间点变为 nil 有效,就使用弱引用。相反,当您知道一旦在初始化期间设置引用将永远不会为零时,请使用无主引用。

在文档中,有一些示例讨论了保留周期以及如何打破它们。所有这些示例都是从docs
中提取的

weak关键字示例:

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
}

class Apartment {
    let number: Int
    init(number: Int) { self.number = number }
    weak var tenant: Person?
}

现在,对于一些 ASCII
艺术(你应该去看看文档——他们有漂亮的图表):

Person ===(strong)==> Apartment
Person <==(weak)===== Apartment

PersonandApartment示例显示了两个属性都允许为 nil
的情况,它们有可能导致强引用循环。这种情况最好用弱参考来解决。两个实体都可以存在而不严格依赖另一个实体。

unowned关键字示例:

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 }
}

在这个例子中,aCustomer可能有也可能没有CreditCard,但是 aCreditCard 总是 与 a
相关联Customer。为了表示这一点,Customer该类具有一个可选card属性,但CreditCard该类具有一个非可选(和无主)customer属性。

Customer ===(strong)==> CreditCard
Customer <==(unowned)== CreditCard

Customerand示例显示了一种情况,其中一个允许为 nil的CreditCard属性和另一个不能为 nil
的属性有可能导致强引用循环。这种情况最好使用无主引用来解决。

苹果的注意事项:

弱引用必须声明为变量,以表明它们的值可以在运行时改变。弱引用不能声明为常量。

还有第三种情况,两个属性都应该始终有一个值,并且一旦初始化完成,两个属性都不应该为 nil。

在使用闭包时,还有一些经典的保留循环场景要避免。

为此,我鼓励您访问Apple
文档
或阅读本书

2022-05-16