为什么在guard语句中检查了用weak self定义的self是否为nil时,弱引用升级为强引用?

问题描述 投票:0回答:1

问题:当self定义为weak self,然后在guard语句中使用可选绑定赋值给变量时,为什么弱引用升级为强引用?

我是一名初学者,拥有大约一个月的 Swift 经验。

最近,我遇到了以下常见的代码:

// refs: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0079-upgrade-self-from-weak-to-strong.md#introduction
networkRequest.fetchData() { [weak self] result in
    guard let strongSelf = self else { return }

    switch result {
    case .Succeeded(let data):
        strongSelf.processData(data)

    case .Failed(let err):
        strongSelf.handleError(err)
    }
}

在此代码中,

self
被定义为弱引用,并且使用guard语句中的可选绑定将值(对
self
的引用?)分配给
strongSelf

这给我提出了一个问题:为什么用

self
定义的
weak self
被分配给像
strongSelf
这样的变量,这似乎是一个强引用?

在研究这个问题时,我发现了一个与该主题相关的提案,它用以下引用解释了这个概念:

如果 self 仍然存在,那么弱捕获的 self 将是非零,并且在闭包执行期间它将被转换为 StrongSelf 持有的强引用。

来源:https://github.com/swiftlang/swift-evolution/blob/main/proposals/0079-upgrade-self-from-weak-to-strong.md#introduction

我不认为这个提议是错误的,但我相信守卫声明只是检查 self 是否为零。所以我不太明白弱引用升级为强引用意味着什么

如果您能解释一下,我将不胜感激。

我参考的文件如下:

这些文档都没有明确提到弱引用在guard语句后升级为强引用,这让我很好奇。

如果您能解释一下,我将不胜感激。

类似的问题:如果警卫引用的对象被释放,那么在使用 [weak self] 的闭包中,守卫是否会让 `self` = self 导致崩溃?

swift closures weak-references strong-references
1个回答
1
投票

您似乎认为强弱属于变量的。事实并非如此。它属于 reference (即变量的名称)。比如说,如果

self
是一个视图控制器,那么它就不是一个“弱视图控制器”,仅仅因为你说
[weak self]
;不存在这样的事情。相反,name
self
是对视图控制器的弱引用

但是

strongSelf
并没有被声明为弱,即你没有说

weak var strongSelf = ...

因此它很强。所以现在我们有一个对视图控制器的strong引用,如果我们能得到一个引用的话。

我们如何获得该参考?好吧,

if let
guard let
展开并分配
[weak self]
规范会导致弱引用,因此可选引用到达块,即
self?
。如果
self
超出范围,则为
nil
。如果没有,您可以在块内将其称为
self?
。但为了避免重复引用
self
,以及它可能在块中途超出范围的可能性,如果它不是
nil
,我们也可以保留它——这正是
if let 
guard let
做。

最后,请注意您的代码已经过时了;你现在应该说

guard let self else { return }

这是

的缩写
guard let self = self else

其本身是

的缩写
guard let `self` = self

换句话说,我们正在解开弱引用

self
并将其分配给一个 different引用
self
,它是强引用,因为我们没有将其声明为弱引用。

© www.soinside.com 2019 - 2024. All rights reserved.