【问题标题】:What is the usage of guard let self = self else { return }守卫 let self = self else { return } 有什么用
【发布时间】:2022-02-07 12:28:51
【问题描述】:

我最近从Sean Allen's video 学到了如何使用Result 类型,我有了使用它的想法。但是,在我写代码的时候,有一行我看不懂。

图片中的行是87(或者这个->guard let self = self else { return }) 起初,我只是在做和他一样的事情,但我想知道他为什么在代码中添加这行代码。我认为他写它是因为 self 可以为 nil,并且想确定 self 是否不为 nil,如果它为 nil,则从函数返回。

我的问题是

  1. 什么时候或者什么情况下 self 可以为零? 和
  2. 如果 self 为 nil,我认为它不会触发以下行(用于检查结果的行),因此不会触发 updateUI 函数和 presentGFAlert... 函数,并且不会显示任何内容屏幕,对吧?

【问题讨论】:

  • NetworkManager.shared.getFollowers这一行,它使用[weak self]。这意味着闭包不是没有持有对self 的引用,因此您需要检查self 是否仍然被分配或已成为nil。这允许在getFollowers 仍在执行时取消引用“父”对象,但要防止它(即尝试在nil 时引用self)并允许父对象在关闭之前超出范围被称为
  • 1) 如果 self 被释放,它可以为 nil。 2) 结果关闭仍然会被触发,因为你的 NetworkManager 是一个单例,即使在 self 被释放后它仍然存在。
  • 一个真实的案例:您将该视图控制器呈现为模式,并希望使用 Web API。您的连接速度很慢,并决定在得到响应之前关闭控制器。闭包将在之后被调用,因此当 ViewController(此处为 self)可能已被释放时。使用[weak self] 防止内存泄漏。

标签: swift self guard resulttype


【解决方案1】:

您的担心是正确的。因为getFollowers 是一个异步任务,所以用户可以在任务运行时返回上一个屏幕。在这种情况下,self 可以是 nilreturn 也可以。

另一方面,为了确保getFollowers 任务的完成块没有问题,self 将被捕获为strong 引用,即使用户已经离开该屏幕也可能导致内存泄漏。 他使用weak self 来防止这种情况发生。

【讨论】:

  • 感谢您的回复!所以,你说的是因为 getFollowers 需要一些时间(异步任务)并且不确定用户是否仍在视图中(或视图控制器?)以获得关注者,我必须确保 self 是否仍然指向是否具有 getFollowers 函数的对象。如果,正如你所提到的,用户已经返回或转到不同的屏幕,我不需要 getFollowers 的成功或失败响应,所以这就是为什么我可以简单地返回并退出 getFollowers 函数?对不起,如果我错了,请纠正我...
  • 是的,它实际上与捕获完成值closure有关,请查看此文档。 docs.swift.org/swift-book/LanguageGuide/Closures.html
【解决方案2】:

这是因为闭包定义了它对self的引用是弱的,这意味着如果self被释放,闭包不会阻止self被销毁,引用计数为0。你可以处理这个在闭包中的代码中,通过使用对 self 的所有引用作为 self?,但这意味着 self 可能在执行的中途变成 nil,通过使用 guard let self = self else { return },你是说如果执行到这里,我想要一个强有力的参考到它,所以对象将继续可用,直到闭包的执行完成,基本上全有或全无。这在过去只可能发生在多线程应用程序中,但随着苹果新的异步线程模型使协作线程更普遍,这更有可能发生。

【讨论】:

  • 实际上更改引用计数是原子的,因此如果尝试在更改中使用对象,则可能会产生问题。但如果它不是原子的,你怎么能原子地获得对 self 的强引用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-21
  • 2018-01-31
  • 2016-02-24
  • 1970-01-01
  • 2018-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多