天天看點

swift ARC

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