Swift:可以在可选绑定期间释放弱引用吗?
Posted
技术标签:
【中文标题】Swift:可以在可选绑定期间释放弱引用吗?【英文标题】:Swift: Can weak reference be deallocated during optional binding? 【发布时间】:2020-11-26 16:11:10 【问题描述】:让我们看看下面的例子
SomeLib.someAsyncFunction [weak someVariable] in
if let someVariableU = someVariable
// now someVariableU is unwrapped and strong reference created , we can use it as regular
我假设可选绑定有一个类似于(当然不完全是)这样的低级实现
if variable != nil
return variable!
所以,我的问题 - 弱引用引用的对象是否有可能在可选绑定期间被释放,我的意思是对该对象的最后一个强引用被“清除”。如果是这样,这种情况会发生什么?
如果“nil 检查通过”然后将被释放会发生什么,“强制展开”会发生什么(我使用括号是因为我知道它不完全是这样工作的)!
那么,有人能解释一下这种情况是否可能发生,而且会发生什么?
【问题讨论】:
看看发出的机器码,你应该看到retain
调用someVariableU
【参考方案1】:
整个结构可以追溯到 Objective-C 时代,传统上被称为“弱-强之舞”。让我解释一下舞蹈的目的。
我们的总体目标是:避免保留周期和内存泄漏的危险。这就是为什么我们说weak somevariable
。
然而,在这样做之后,我们确实引入了somevariable
指向的对象可能被释放的危险。但是,我们通过说if let
连贯地处理这种危险。方法如下:
当我们在您的代码中输入 first 花括号时,对象可能已被释放。但这不是问题。 if let
表示如果对象已被释放,那么在这种情况下,我们将得到 nil
,但我们什么也不做(我们从不输入 second 花括号)。
如果对象没有被第一个花括号释放,然后if let
成功,然后,正如Cristik所说,if let
创建了一个强引用,现在我们输入 second 大括号,保证对象将保持完整。
因此,我们得到连贯一致的行为。
SomeLib.someAsyncFunction // someVariable might be deallocated...
[weak someVariable] in // ...and that is the point of `weak`, to allow that
if let someVariableU = someVariable // find out whether someVariable was deallocated
// if we get here, someVariable was _not_ deallocated...
// and someVariableU is a strong reference and persists thru this block
【讨论】:
感谢您的回答!它解释了很多事情!所以,基本上要澄清 - 我想知道是否可以在if/guard let
语句本身期间释放弱引用的对象。我的意思是如果让语句(内部实现)必须首先检查变量是否确实具有值(未释放),然后才打开它。我的意思是可以在这些步骤之间进行重新分配吗?或者它是由某种“原子”操作制成的,在一次操作中完成所有这些步骤?
是的,说if let
的那一刻是原子的。我了解您认为这是两个步骤:(1)这件事还在吗? (2) 如果是,请打开它。但这不是两个步骤,至少不是在 1 和 2 之间可能发生的某种意义上。
换句话说,如果if let
不是原子的,那么整个宇宙现在已经爆炸了。但事实并非如此。 :)
基本上你是在问 ARC weak 的魔力是如何在幕后工作的。答案是,只要对对象的弱引用没有被簿记系统手动清零,该对象就有一个额外的保留计数,正是这样if let
之类的东西才能正确运行。相反,当所有强引用都消失时,弱引用被手动清零并且额外的保留计数减少——对象消失。
实际上我猜它是这样工作的,直到 Swift 4。对象被保留,直到它的所有弱引用都被清零。由于 Swift 4 objs 不存储弱引用计数以及直接在 obj 中引用它们自己!所以,基本上 obj 是“活的”,直到所有指向它的弱引用都被手动清零。【参考方案2】:
不,在执行可选绑定块期间不会释放对象。
if let someVariableU = someVariable
创建一个强引用,因此只要该强引用存在,它指向的对象也会存在。
【讨论】:
以上是关于Swift:可以在可选绑定期间释放弱引用吗?的主要内容,如果未能解决你的问题,请参考以下文章