14.6 Swift中weak解决循环强引用

        /**

         6)循环强引用

         ARC不是万能的,它可以很好的解决内存过早释放的问题,

         但是在某些场合下不能很好的解决内存泄漏的问题。

         */

        

        /**

         循环强引用是造成内存泄漏的原因。接下来我们还是用代码来给大家讲解什么是循环强引用。

         直接用官方例子

         */

        

        class Person {

            let name:String

            init(name:String) {

                self.name = name

            }

            var apartment:Apartment?

            deinit {

                print("\(name) is being deininialized")

            }

        }

        

        

        class Apartment {

            let number:Int

            init(number:Int) {

                self.number = number

            }

            var tenant:Person?

            deinit {

                print("Apartment #\(number) is being deininialized")

            }

        }

        

        /**

         两个类各有一个属性,每个属性都是对方类的类型的属性,而这两个属性互相持有对方。

         这就是所谓的循环强引用

         */

        

        // 这是强引用,不要认为可选类型就是弱引用啊,只有通过weak unowned才是弱引用

        var john:Person?

        var number73:Apartment?

        

        john = Person.init(name:"Johu Appleseed")

        number73 = Apartment.init(number:73)

        

        /**

         上面的四句换对应 循环强引用讲解图1.png

         */

        

        




        /**

         这里面 apartment tenant两个对象是强引用,

         也就是下面的johnnumber73设置为nil只是他们的强引用断开。

         */

        john!.apartment = number73

        number73!.tenant = john

        

        

        

        /**

         我们可以看到在析构方法中没有打印,也就是这两个对象他们没有被销毁,造成了内存泄漏。但是我们没有办法在访问他们。

         对应的循环强引用讲解图2.png

         */

        john = nil

        number73 = nil

        

        

        

        /**

         相互强引用或者说循环强引用会造成内存泄漏,为什么?

         因为一块内存的释放的判断是没有对象占用它,相互强引用,那到底谁先释放呢?谁也不愿意先释放。

         */

        

        



        

        

        

        

        

        

        

        

        

        

        /**

         在变量tenant加上 weak修饰,

         也就是将其中的一个变量设置为弱引用就行了。

         */

        

        class Apartment1 {

            let number:Int

            init(number:Int) {

                self.number = number

            }

            weakvar tenant: Person?

            deinit {

                print("Apartment #\(number) is being deininialized")

            }

        }

        

        print("--------------------->>")

        

        

        var john1:Person?

        var number74:Apartment1?


        john1 = Person.init(name:"Johu Appleseed1")

        number74 = Apartment1.init(number:74)

        

        /**

         上面的四句换对应 循环强引用讲解图3.png

         */

        

        

        /**

         这里面 apartment tenant两个对象是强引用,

         也就是下面的johnnumber73设置为nil只是他们的强引用断开。

         */

        john1!.apartment = number73

        number74!.tenant = john

        

        

        /**

         打印出来

         --------------------->>

         Apartment #74 is being deininialized

         Johu Appleseed1 is being deininialized


         循环强引用讲解图4.png

         

         john1 对象的强引用没有了,设置为nil时被销毁,释放内存。同时number74所指向的内存也被释放了。

         */

        john1 = nil

        number74 = nil


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值