Swift中的强引用,弱引用和无主引用
Swift依靠自动引用计数(ARC)通过在对象的强引用为零时释放对象的内存来管理对象的生命周期。 但是,当两个对象彼此保持强引用时,可能会发生强引用循环。
强烈 参考
强大的参考保护 ARC释放对象后,其保留计数增加1。
默认情况下,对类实例的引用是强的。 基本上,只要任何东西都强烈引用对象,就不会释放该对象。 如下面的示例所示,当流程是从父级到子级时,可以使用强引用。
当我们将对象设置为nil时,会同时调用instrument和player deinit方法。
强参考循环–内存泄漏
现在,我们将一个玩家数组添加到Instrument实例(第3行),并在初始化一个Player实例(第5行)时,将其添加到该乐器的玩家数组(第22行)。
当我们将实例设置为nil时,不会调用instrument和player的deinit方法。
当我们将乐器实例设置为nil时,ARC会检查是否有一个实例保留对其的强引用,并且由于存在一个播放器实例对其具有强引用,因此不会释放该对象( 强引用周期 ),这导致我们陷入所谓的内存泄漏 。
弱引用
弱引用不能防止对象被ARC释放(它不会将其保留计数增加1),并且始终是可选的 。
弱引用只是指向对象的指针,该指针不能保护对象免遭ARC释放。 当不再有对它的强引用时,该引用将被更改为nil。
我们可以使用弱引用以避免强引用周期和内存泄漏(第17行):
当Instrument设置为nil时,唯一引用该实例的实例是播放器实例,并且由于它是弱引用,因此ARC会释放Instrument实例。
多余的参考
无主引用类似于弱引用(ARC不会将其保留计数增加1),但是具有额外的好处,这是非可选的。
无主引用是非归零的。 这意味着当对象被释放时,它不会使指针归零。 正如我们在下面的示例中看到的那样,将弱引用(第17行)更改为无主引用,其结果与以前相同。
根据Apple的文档:
仅当确定引用始终引用尚未取消分配的实例时,才使用无主引用。
如果在释放该实例后尝试访问一个未拥有的引用的值,则会收到运行时错误。