Auto Reference Counting

本文深入探讨Swift中的内存管理机制,包括强引用、弱引用、无主引用的概念及其应用场景,解析如何避免强引用死锁,并介绍类中引用闭包可能产生的问题及解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/* 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")

    }

    

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值