问题:当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 持有的强引用。
我不认为这个提议是错误的,但我相信守卫声明只是检查 self 是否为零。所以我不太明白弱引用升级为强引用意味着什么
如果您能解释一下,我将不胜感激。
我参考的文件如下:
这些文档都没有明确提到弱引用在guard语句后升级为强引用,这让我很好奇。
如果您能解释一下,我将不胜感激。
类似的问题:如果警卫引用的对象被释放,那么在使用 [weak self] 的闭包中,守卫是否会让 `self` = self 导致崩溃?
您似乎认为强弱属于变量的值。事实并非如此。它属于 reference (即变量的名称)。比如说,如果
self
是一个视图控制器,那么它就不是一个“弱视图控制器”,仅仅因为你说 [weak self]
;不存在这样的事情。相反,nameself
是对视图控制器的弱引用。
但是
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
,它是强引用,因为我们没有将其声明为弱引用。