1.解决实例之间的循环强引用
(1)弱引用 : 声明属性或者变量时,在前面加上 weak 关键字
(2)无主引用 : 和弱引用类似 ,和弱引用不同的是,无主引用在其他实例有相同或者更长 的生命周期时使用 ,在关键字前加 unowned
注意:
使用无主引用,你必须确保引用始终指向一个未销毁的实例。 如果你试图在实例被销毁后,访问该实例的无主引用,会触发运行时错误。
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") }
}
总结:weak常用在可选类型(两个属性的值都允许为 nil ),unowned常用在非可选类型(一个属性的值允许为 nil ,而另一个属性的值不允许为 nil )
2.第三种场景 :两个属性都必须有值,并且初始化完成后永远不会为 nil 。在这种场 景中,需要一个类使用无主属性,而另外一个类使用隐式解析可选属性
class Country {
let name: String
var capitalCity: City!
init(name: String, capitalName: String) {
self.name = name
self.capitalCity = City(name: capitalName, country: self)
}
}
class City {
let name: String
unowned let country: Country
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
3.闭包引起的循环强引用
(1)注意:Swift 有如下要求:只要在闭包内使用 的成员,就要用 self.someProperty 或者 self.someMethod() (而 不只是 someProperty 或 someMethod() )。这提醒你可能会一不小心就捕获了 self
(2)在闭包和捕获的实例总是互相引用并且总是同时销毁时,将闭包内的捕获定义为 无主引用 。
(3)相反的,在被捕获的引用可能会变为 nil 时,将闭包内的捕获定义为 弱引用 。弱引用总是可选类型,并且当引用 的实例被销毁后,弱引用的值会自动置为 nil 。这使我们可以在闭包体内检查它们是否存在
(4)注意:如果被捕获的引用绝对不会变为 nil ,应该用无主引用,而不是弱引用
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: Void -> String = {
[unowned self] in
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) is being deinitialized")
} }
来源:https://www.cnblogs.com/zhangjie579/p/6675471.html