Auto Reference Counting

/* ARC 感觉跟python太像了有木有。Automatic Reference Counting

✨✨Unowned reference其实也是一种weak引用,它的意思是当它处于不被拥有时,它就变为无效。

从另一方面讲unowned定义的引用,通常被认为必须要有效的,一旦指向的对象被释放,就变得没有意义。

class Person { var card: CreditCard? } class CreditCard { unowned let holder: Person init (holder: Person) { self.holder = holder } }

weak指向的对象被释放变为nilunowned指向的对象被释放后不会变为nil,被调用时会出现异常。

所以这两个使用的对象就不一样了,当是可有可无的关系,

比如房屋和租户可以相互不拥有,则房屋类中  weak 租户租户

但是信用卡和拥有者 ,信用卡的类中不可以缺少拥有者  unowned拥有者 拥有者


1.强引用

2.强引用死锁

3.弱引用(weak reference),弱引用代表其随时都会被赋值为nil

    所以不能是const,并且需要是optional的。

4.无主引用(Unowned reference


在被赋值之后很可能会变成nil的变量,尽量使用弱引用,相反在被赋值后不会变成nil的变量尽量用无主引用。

比如 dat var,如果执行这句之后,var很可能变成nil则弱引用,若永远不会变成nil则无主引用。

如果变量vardeinit后,dat会自动变为nil


与弱引用总是定义为optional相反,无主引用总是定义为非optional的。

✨✨ 在beta5中如果想前向引用,则与所引用的类型中间不能有实例定义但是允许类型定义,参见下面Person例子 */

class Person

{

   let name:String

    //✨✨beta3中如果想引用未定义的类型则其类型定义必须紧随该变量,中间不能有实例定义

    //但是允许类型定义

   var apartment:Apartment?

   init(name:String)

    {

       self.name = name

        println("\(name) is initialized!")

    }

    

    deinit//注意deinit没有小括号

    {

       println("\(name) is deinit")

    }

}


// var testFowardRefenerce:Person? 如果有这个定义,Person中就不认识Apartment

class TMP //类型定义是可以的。

{

}


/* 2.强引用死锁 */

class Apartment

{

   var person:Person?

}


var ref1:Person?

var ref2:Person?


ref1Person(name:"A")

println("1")

ref2 = ref1//现在ref1ref2都对Person对象进行了Strong reference

println("2")

ref1 = nil//删除ref1还有ref2的强引用,所以不会调用析构函数

println("3")

ref2nil//这个变量也被删除,则没人再引用Person,这时会调用析构函数。

println("4")


var a:Apartment? =Apartment()

var p:Person? =Person(name:"Person")


p!.apartment = a

a!.person = p


p = nil//由于pa中被强引用,所以不能deinit

a = nil//由于p没有被deinitp还存在,而ap引用造成死锁。


/* 3.弱引用语法在前面加weak关键字 */

class WeakApartment

{

   weak var person:Person?

}


/* 4.无主引用 

无主引用理解起来感觉比较困难,我的理解是必须有主才行,如果类实例的无主类型只想的类型被nil

那么类实例本身会被deinit

*/

class Unowned

{

   unowned var p:Person //无主引用被定义为非optional的。

   var test:Int = 3

    

   init(p:Person)

    {

       self.p = p

        println("Unowned is init")

    }

    deinit

    {

        println("Unowned is deinit")

    }

}


var person:Person? =Person(name:"Person")

var unowned:Unowned? =Unowned(p:person!)

person = nil

//unowned = nil

println(unowned!.p)//weaknil不同,没有主人后,是不可以访问的。



/* 类中引用闭包,闭包中capture类中的成员造成的引用锁解决办法 

[unowned self]

*/


class HTMLElement {

    

   let name:String

   let text:String?

    

   @lazyvar asHTML: () ->String = {

        //如果不加上unowned selfasHTML被赋值给外部后,产生了外部强引用

        //闭包内部引用name等,不能析构,而闭包内部又无法被删除导致死锁。

        [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 {

        println("\(name) is being deinitialized")

    }

    

}


你可能感兴趣的:(Auto Reference Counting)