Published on

weak和unowned在Swift中的用法

Authors
  • Name
    Twitter

weak和unowned都是自动引用计数(ARC)内存管理下的关键字。 其中weak表示弱引用,如果其引用计数变成0,那么这个对象会被置为nil。根据这个特性,weak只能修饰Optional的类型。因为其值有可能为nil。 其中unowned的作用是也不会增加引用计数的值,但是必须保证对象在使用期间不被释放。是非Optional类型。

class Customer {
    let name: String
    var card: CreditCard?

    init(name: String) {
        self.name = name
    }

    deinit {
        print("\(name) 被释放了")
    }
}

class CreditCard {
    let number: UInt64
    unowned let customer: Customer //每一张信用卡,一定会有主人
    init(number: UInt64, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    deinit {
        print("信用卡 \(number) 被释放了")
    }
}

var tom: Customer? = Customer(name: "Tom")
tom?.card = CreditCard(number: 1234_5678, customer: tom!)

tom = nil

这是一个互相持有的例子,如果没有unonwed来修饰CreditCard中的customer,那么就会出现强引用循环,这两个类实例都不会被释放。 如何添加unowned,那么当我们将tom置为nil的时候,tom和tom.card都会释放。没有强引用循环了。

这里为什么不用weak而是要用unowned,这是由customer是不是可选类型来决定的。每一张信用卡,都会有一个主人,只要信用卡存在,customer就不会为nil,所以这里使用unowned。

在闭包的使用

当闭包和它捕获的实例总是相互引用,并且总是同时被释放时,将闭包中的捕获定义为无主引用 unowned 相反,当被捕获的引用在将来某个时刻可能变成 nil 时,将捕获定义为弱引用。弱引用总是可选类型,并且当它们引用的实例被释放时自动变成 nil。这使得你能够在闭包体内检查它们是否存在。