美文网首页
Swift5.1—无主引用

Swift5.1—无主引用

作者: anny_4243 | 来源:发表于2020-07-08 15:37 被阅读0次

和弱引用类似,无主引用不会牢牢保持住引用的实例。和弱引用不同的是,无主引用在其他实例有相同或者更长的生命周期时使用。你可以在声明属性或者变量时,在前面加上关键字 unowned 表示这是一个无主引用。

无主引用通常都被期望拥有值。不过 ARC 无法在实例被销毁后将无主引用设为 nil,因为非可选类型的变量不允许被赋值为 nil

重点

使用无主引用,你必须确保引用始终指向一个未销毁的实例。

如果你试图在实例被销毁后,访问该实例的无主引用,会触发运行时错误。

下面的例子定义了两个类,CustomerCreditCard,模拟了银行客户和客户的信用卡。这两个类中,每一个都将另外一个类的实例作为自身的属性。这种关系可能会造成循环强引用。

CustomerCreditCard 之间的关系与前面弱引用例子中 ApartmentPerson 的关系略微不同。在这个数据模型中,一个客户可能有或者没有信用卡,但是一张信用卡总是关联着一个客户。为了表示这种关系,Customer 类有一个可选类型的 card 属性,但是 CreditCard 类有一个非可选类型的 customer 属性。

此外,只能通过将一个 number 值和 customer 实例传递给 CreditCard 构造器的方式来创建 CreditCard 实例。这样可以确保当创建 CreditCard 实例时总是有一个 customer 实例与之关联。

由于信用卡总是关联着一个客户,因此将 customer 属性定义为无主引用,用以避免循环强引用:

class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) {
        self.name = name
    }
    deinit { print("\(name) is being deinitialized") }
}

class CreditCard {
    let number: UInt64
    unowned let customer: Customer
    init(number: UInt64, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    deinit { print("Card #\(number) is being deinitialized") }
}

注意

CreditCard 类的 number 属性被定义为 UInt64 类型而不是 Int 类型,以确保 number 属性的存储量在 32 位和 64 位系统上都能足够容纳 16 位的卡号。

下面的代码片段定义了一个叫 john 的可选类型 Customer 变量,用来保存某个特定客户的引用。由于是可选类型,所以变量被初始化为 nil

var john: Customer?

现在你可以创建 Customer 类的实例,用它初始化 CreditCard 实例,并将新创建的 CreditCard 实例赋值为客户的 card 属性:

john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)

在你关联两个实例后,它们的引用关系如下图所示:

Customer 实例持有对 CreditCard 实例的强引用,而 CreditCard 实例持有对 Customer 实例的无主引用。

由于 customer 的无主引用,当你断开 john 变量持有的强引用时,再也没有指向 Customer 实例的强引用了:

由于再也没有指向 Customer 实例的强引用,该实例被销毁了。其后,再也没有指向 CreditCard 实例的强引用,该实例也随之被销毁了:

john = nil
// 打印“John Appleseed is being deinitialized”
// 打印“Card #1234567890123456 is being deinitialized”

最后的代码展示了在 john 变量被设为 nilCustomer 实例和 CreditCard 实例的析构器都打印出了“销毁”的信息。

注意

上面的例子展示了如何使用安全的无主引用。对于需要禁用运行时的安全检查的情况(例如,出于性能方面的原因),Swift 还提供了不安全的无主引用。与所有不安全的操作一样,你需要负责检查代码以确保其安全性。 你可以通过 unowned(unsafe) 来声明不安全无主引用。如果你试图在实例被销毁后,访问该实例的不安全无主引用,你的程序会尝试访问该实例之前所在的内存地址,这是一个不安全的操作。

相关文章

  • Swift5.1—无主引用

    和弱引用类似,无主引用不会牢牢保持住引用的实例。和弱引用不同的是,无主引用在其他实例有相同或者更长的生命周期时使用...

  • Swift中的弱引用weak和无主引用unowned

    1. 什么是弱引用和无主引用? 2. 弱引用 3. 无主引用

  • Swift中的循环强引用--【使用无主引用解决】

    无主引用(unowned) 声明属性或者变量时,在前面加上unowned关键字表示这是一个无主引用,无主引用不能设...

  • Swift weak和unowned

    弱引用和无主引用 在闭包和捕获的实例总是互相引用并且总是同时释放时,将闭包内的捕获定义为无主引用。 相反,在被捕获...

  • Swift 内存管理

    Swift 中使用自动引用计数(ARC)机制来追踪和管理内存 强引用strong和无主引用unowned 通过阅读...

  • RxSwift-内存管理

    一、循环引用 weak:弱引用,[weak self],需要解包操作,延迟调用为nil不崩溃 unowned:无主...

  • 笔记摘要(十一)--Swift3.0之解决实例/闭包的循环强引用

    解决实例之间的循环强引用可以通过定义类之间的关系为弱引用或无主引用,以替代强引用,从而解决循环强引用的问题。对于生...

  • Swift5.1—隐式解包可选值属性

    上面弱引用和无主引用的例子涵盖了两种常用的需要打破循环强引用的场景。 Person 和 Apartment 的例子...

  • Swift之weak和unowned

    Swift 提供了两种方法解决你在使用类的属性而产生的强引用循环:弱引用( weak )和无主引用( unowne...

  • Swift5.1—自动引用计数

    Swift 使用自动引用计数(ARC)机制来跟踪和管理你的应用程序的内存。通常情况下,Swift 内存管理机制会一...

网友评论

      本文标题:Swift5.1—无主引用

      本文链接:https://www.haomeiwen.com/subject/phxccktx.html