class Person{
var name: String
init(name:String){
self.name=name
print("\(name) allocated")
}
deinit{
print("\(name) deallocated")
}
}
var ref1:Person?//by default nil
var ref2:Person?
var ref3:Person?
class Tenant{
var name:String
var apartment:Apartment?
init(name:String){
self.name=name
}
deinit{
print("\(name) is deallocated")
}
}
class Apartment{
var roomid:Int
var tenant:Tenant?
init(roomid:Int){
self.roomid=roomid
}
deinit{
print("\(roomid) is deallocated")
}
}
var ppl1:Tenant? =Tenant(name: "zhangsan")// use ? to nil it later
var room1:Apartment? =Apartment(roomid: 1)
ppl1!.apartment =room1 // use ! to unwrap
room1!.tenant =ppl1
ppl1=nil ;room1=nil// notice that both instance didn't quote deinit{}
class Tenant2{
var name:String
weak var apartment:Apartment2?
init(name:String){
self.name=name
}
deinit{
print("\(name) is deallocated")
}
}
class Apartment2{
var roomid:Int
weak var tenant:Tenant2?
init(roomid:Int){
self.roomid=roomid
}
deinit{
print("\(roomid) is deallocated")
}
}
var ppl2:Tenant2?=Tenant2(name:"Lisi")
var appart2:Apartment2?=Apartment2(roomid:2)
ppl2?.apartment=appart2
appart2?.tenant=ppl2
ppl2=nil// print Lisi is deallocated
class Tenant3{
var name:String
unowned var apartment:Apartment3
init(name:String,apartment:Apartment3){
self.name=name
self.apartment=apartment
}
deinit{
print("\(name) is deallocated, because of no room")
}
}
class Apartment3{
var roomid:Int
var tenant:Tenant3?
init(roomid:Int){
self.roomid=roomid
}
deinit{
print("room\(roomid) is deallocated")
}
}
var apart3:Apartment3?=Apartment3(roomid:3)
//Question here
//Approach A will not call deinit of Tenant3
var ternant3:Tenant3?=Tenant3(name:"wangwu", apartment: apart3!)
apart3?.tenant=ternant3
//Approach B will call deinit of Tenant3
// apart3?.tenant=Tenant3(name: "wangwu", apartment: apart3!)
ternant3=nil
apart3=nil
// Question here, when you use upper case C below, make country -> Country
// unexpected error
class City{
var name:String
var country:Country! // when you use var Country:Country! it will error
init(name:String,countryName:String){
self.name=name
self.country=Country(name:countryName,city:self)
}
}
class Country{
var name:String
unowned var Capital:City
init(name:String,city:City){
self.name=name
self.Capital=city
}
}
var city = City(name:"hangzhou",countryName:"zhongguo")
// Strong reference cycle with Closure
class A{
var name:String?
var age:Int
lazy var speak:()->String = {
if let name = self.name{
return "\(self.name) got a name"
}else{
return "ain't got no name, but he got \(self.age)"
}
}
init(name:String?,age:Int){
self.name=name
self.age=age
}
deinit{
print("A class now been terminated and deallocated")
}
}
var a:A? = A(name: nil, age: 3)
//a=nil // this can run successfully
a?.speak()
//a=nil // until now, a string reference cycle been created, you cant release
class B{
var name:String?
var age:Int
lazy var speak:()->String = {
[unowned self] in
if let name = self.name{
return "\(self.name) got a name"
}else{
return "ain't got no name, but he got \(self.age)"
}
}
init(name:String?,age:Int){
self.name=name
self.age=age
}
deinit{
print("A class now been terminated and deallocated")
}
}
var b:B? = B(name: nil, age: 3)
b?.speak()
b=nil