Swift 什么';使用“s”和“s”的区别是什么;“自我”;前缀和书写“;“自我”;在关闭的捕获列表中?

Swift 什么';使用“s”和“s”的区别是什么;“自我”;前缀和书写“;“自我”;在关闭的捕获列表中?,swift,closures,Swift,Closures,我正在编写一些类似以下内容的代码: class ViewController : UIViewController { var foo = "foo" override func viewDidLoad() { let alert = UIAlertController(title: "", message: "", preferredStyle: .alert) alert.addAct

我正在编写一些类似以下内容的代码:

class ViewController : UIViewController {
    var foo = "foo"
    override func viewDidLoad() {
        let alert = UIAlertController(title: "", message: "", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "", style: .default, handler: { _ in
            print(foo)
        }))
    }
}
Xcode在
print(foo)
报告了一个错误,我忘记捕获
self
,并建议了两个修复方法:

  • 打印(self.foo)
    ,或

  • [self]
    的捕获列表添加到闭包:
    。。。处理程序:{[self]\uIn…

  • 现在,我记得在Xcode 12/Swift 5.3之前,它没有这样做。它要么没有给出修复,要么只是第一个修复

    我的问题是,这两个修复之间有什么区别?它们是否以不同的方式捕获了
    self


    似乎有点触及这一点,但似乎没有说明它们之间的区别。

    这两个在功能上是相同的,都明确地捕获了
    自我
    模式避免了在闭包中重复使用
    self.
    引用(如果有多个属性和/或方法引用)。但它们都做完全相同的事情,捕获
    self

    正如你提到的那份文件所说:

    通常,闭包通过在闭包体中使用变量来隐式捕获变量,但在这种情况下,需要显式捕获。如果要捕获
    self
    ,请在使用时显式写入
    self
    ,或者在闭包的捕获列表中包含
    self

    说到底,它们是一样的


    出于价值考虑,另一种选择是避免完全捕获
    self
    。例如,您可能只捕获
    foo

    alert.addAction(UIAlertAction(title: "", style: .default) { [foo] _ in
        print(foo)
    })
    

    阅读语言指南:“这里有一个doSomething()版本,它通过在闭包的捕获列表中包含self来捕获self,然后隐式地引用self”(与前面的1或2句相反),这意味着捕获
    [self]
    允许在整个过程中隐式引用self来编写转义闭包(vs必须显式编写)。因此,似乎这只是一个优先事项。这是Swift v5.3中实现的一个新功能:-在不太可能发生引用循环的情况下,提高
    @转义
    闭包中隐式
    self
    的可用性