swift 笔记 (十五) —— 析构过程、ARC

本文介绍了Swift语言中的内存管理机制ARC,并详细讨论了析构过程、实例间的循环引用及其实现方式。此外,还提供了弱引用和无主引用的概念以解决循环引用问题。

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

析构过程
析构过程是构造过程的逆向过程,当一个类的实例被释放的时候,在内存中消失前,析构器会被调用。

swift依然通过ARC管理内存。ARC相关内容,在后面会说。

原型
deinit{
     //清理工作在这里
}

由于swift是ARC管理内存,所以析构过程已经不像c++那么重要了。

class MyClass {
     var myNum = 0

     init() {
          myNum = 1
     }

     deinit {
          myNum = 0
          println(“myNum \(myNum)")
     }
}

var myInstance:MyClass? = MyClass()
println(myInstance!.myNum)
myInstance = nil   //deinit在此时被自动调用


ARC
ARC机制会跟踪每一个实例正在被多少属性,常量以及变量所引用,只要这个实例的引用数不为0,那么这个实例就不会被销毁。那么它的deinit也不会被调用。

文档中,这一章,只讲了两件事儿:
1. 实例之间的循环引用是怎么发生的。
2. 如何消除循环引用导致的内存泄露。

文档用了满多的篇幅写了这两件事,足以说明,ARC并不像想像中那么美好,虽然不像C/C++中那样,要求程序员用一些精力来管理内存,但ARC也并没有把这种精力降低了多少,反而,一切看似美好的东西,导致的难查的BUG会更难查。对底层机制隐藏的太多,导致程序员的底层思维得不到锻炼的结果吧。

这一章,没什么太多想说的,管方的图解已经比文字表达的要清晰得多了,所以只是留些图,便于查阅。


下面的图解,基于这两个类。这里可以看到,两个类里都分别有另一个类的可选类型的变量。那么,结果就是导致了他们互相持有对方的handle:


懂OO的都知道,这种情况是强关联。

在ARC中,当把john 和 number73都赋值为nil的时候,虽然看似断掉了john和number73这两个引用了,但是,在实例中,还有apartment 与 tenant两个引用没有断掉,于是,我们会想到,把这两个写到deinit中去,让他们断开引用关系:

在Person类中的deinit中加入:
apartment = nil

在Apartment类中的deinit中加入:
tenant = nil

但是,这样依然不行,因为在前面我们说过,deinit是在实例被释放的时候发生的,而实例的释放又是在ARC管理中的实例引用计数为0的时候发生的。所以,deinit并不会被调用。这样就导致了内存泄漏。所以,无论如何,都不可以出现两个实例互相强引用的情况,必然导致内存泄漏。

弱引用
为了解决上面的循环强引用,引入一个叫做“弱引用”的方式,关键字是weak:




这样的话,weak引用,不会阻止ARC回收实例,也就是说,一个实例,如果没有被强引用,哪怕有成百上千个弱引用持有它的话,它依然可以被释放。(weak可能会导致引用计数不增加?我不知道答案)

无主引用(Unowned References)
与刚刚说的弱引用,作用是一样,但弱引用是给可选型用的,而无主引用是给非可选型用的





闭包导致的循环强引用



当HTMLElement类的实例在初始化的时候,闭包作为asHTML属性的默认值,与HTMLElement的实例之间建立了强引用关系,也就是我们开始提到无论如何都不要发生的事情。。。。


我们需要让闭包变成无主引用(前面说过,弱引用是给可选型用的,而这里闭包明显不是一个可选型):



在闭包中,使用 [unowned self] in

总结
从上面的例子可以看得出来,在引用关系中,我们可以分得出上下级关系(类的实例为最上级),所有的下级引用上级的情况,要么定义为弱引用(可选型),要么定义为无主引用,就可以避免循环引用而导致的内存泄漏


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值