在闭包的捕获列表中使用 "self." 前缀和写 "self" 有什么区别?
What's the difference between using the "self." prefix and writing "self" in the capture list of a closure?
我正在编写一些类似于以下的代码:
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
,并建议 两个 修复。:
print(self.foo)
, 或;
将[self]
的捕获列表添加到闭包中:... handler: { [self] _ in ...
现在,我记得在 Xcode 12/Swift 5.3 之前,它并没有这样做。它要么不提供修复,要么只提供第一个修复。
我的问题是,这两个修复有什么区别?他们是否以某种方式以不同的方式捕获 self
?
Language Guide好像稍微提到了一点,但是好像没有说出它们的区别。
这两个在功能上是相同的,都明确捕获 self
。如果您有多个 属性 and/or 方法引用,[self]
模式可以避免在闭包中重复使用 self.
引用。但他们都做同样的事情,捕获 self
.
正如您参考的那个文件所说:
Normally, a closure captures variables implicitly by using them in the body of the closure, but in this case you need to be explicit. If you want to capture self
, write self
explicitly when you use it, or include self
in the closure’s capture list.
归根结底,它们是同一回事。
尽管如此,另一种选择是完全避免捕获 self
。例如。你可能只会捕获 foo
:
alert.addAction(UIAlertAction(title: "", style: .default) { [foo] _ in
print(foo)
})
我正在编写一些类似于以下的代码:
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
,并建议 两个 修复。:
print(self.foo)
, 或;将
[self]
的捕获列表添加到闭包中:... handler: { [self] _ in ...
现在,我记得在 Xcode 12/Swift 5.3 之前,它并没有这样做。它要么不提供修复,要么只提供第一个修复。
我的问题是,这两个修复有什么区别?他们是否以某种方式以不同的方式捕获 self
?
Language Guide好像稍微提到了一点,但是好像没有说出它们的区别。
这两个在功能上是相同的,都明确捕获 self
。如果您有多个 属性 and/or 方法引用,[self]
模式可以避免在闭包中重复使用 self.
引用。但他们都做同样的事情,捕获 self
.
正如您参考的那个文件所说:
Normally, a closure captures variables implicitly by using them in the body of the closure, but in this case you need to be explicit. If you want to capture
self
, writeself
explicitly when you use it, or includeself
in the closure’s capture list.
归根结底,它们是同一回事。
尽管如此,另一种选择是完全避免捕获 self
。例如。你可能只会捕获 foo
:
alert.addAction(UIAlertAction(title: "", style: .default) { [foo] _ in
print(foo)
})