class Person {
let name: String
init(name: String) {
self.name = name
print("Person:\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
var reference1:Person?
var reference2:Person?
var reference3:Person?
reference1 = Person(name: "iyaqi") //此时会打印:Person:iyaqi is being initialized
reference2 = reference1
reference3 = reference2
reference3 = nil
reference2 = nil
reference1 = nil // iyaqi is being deinitialized 在这才回销毁,因为有三个指针指向这块内存地址。arc 会再没有强指向的时候销毁该对象,收回地址
1.循环强引用
class Customer {
let name : String
init(name:String){self.name = name}
var apartment:Apartment?
deinit{
print("\(name)is being deinited")
}
}
class Apartment {
let unit :String
init(unit:String){self.unit = unit}
weak var customer:Customer? // 加个weak 相当于apartment 的customer对象是弱引用,这样就不会引起强引用
deinit{print("Apartment \(unit) is being deinited")}
}
var customer:Customer?
var apartment:Apartment?
customer = Customer.init(name: "iyaiq")
apartment = Apartment(unit: "19900619")
customer!.apartment = apartment
apartment!.customer = customer
//这两个操作不会触发任何deinit动作,因为相互引用,不会释放 加个weak ,就能解决这个问题
customer = nil
apartment = nil
//无主引用
class People{
let name:String
var card:CreditCard?
init(name:String){
self.name = name
}
deinit{print("name:\(name) is deinit")}
}
class CreditCard {
let number:Int64
unowned let people:People
init(number:Int64,people:People){
self.number = number
self.people = people
}
deinit{print("CreditCard \(number) id deinit")}
}
var people :People?
people = People(name: "iyaqi")
let card = CreditCard(number: 1990, people: people!)
people!.card = card
people = nil //当people销毁的时候,这两个对象都会被销毁 Apartment 19900619 is being deinited,iyaqi is being deinitialized
2.无主引用和隐式解析
class Country {
let name:String
var city:City!
init(name:String,city:String){
self.name = name
self.city = City(name:city, country: self)
}
deinit{print("Country:\(name) is deinit")}
}
class City {
let name:String
unowned var country:Country
init(name:String,country:Country){
self.name = name
self.country = country
}
deinit{print("city:\(name) is deinit")}
}
var country:Country? = Country(name: "China", city: "beijing")
var city:City? = City(name: "beijing", country:country!)
print("\(city!.name)") //beijing
city = nil //city:beijing is deinit
country = nil //Country:China is deinit
3.闭包引起的循环强引用
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("htmlElement is deinited")
}
}
var htmlElement:HtmlElement? = HtmlElement(name:"p")
let defaultText = "some default text"
htmlElement!.asHTML = {
return "<\(htmlElement!.name)>\(htmlElement!.text ?? defaultText)</\(htmlElement!.name)>"
}
print(htmlElement!.asHTML()) // <p>some default text</p>
htmlElement = nil//htmlElement is deinited 此时会触发deinit,因为在闭包没有使用self
var testHtmlElement:HtmlElement? = HtmlElement(name:"p",text:"hello world")
print(testHtmlElement!.asHTML()) //<p>hello world</p>
testHtmlElement = nil //此时并不会触发deinit,因为在闭包中使用了self