Reputation: 271875
I was writing some code similar to:
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 reports an error at print(foo)
that I forgot to capture self
, and suggests two fixes.:
print(self.foo)
, or;
Add a capture list of [self]
to the closure: ... handler: { [self] _ in ...
Now, I remember that before Xcode 12/Swift 5.3, it didn't use to do that. It either gives no fixes, or just the first one.
My question is, what's the difference between these two fixes? Do they somehow capture self
in a different way?
The Language Guide seems to touch on this a little bit, but doesn't seem to say what the difference between them is.
Upvotes: 3
Views: 186
Reputation: 437672
These two are functionally the same, both explicitly capturing self
. The [self]
pattern avoids having to litter the closure with repeated self.
references if you had multiple property and/or method references. But they both do precisely the same thing, capturing self
.
As that document you reference says:
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.
Bottom line, they’re the same thing.
For what it’s worth, the other option is to avoid capturing self
altogether. E.g. you might only capture foo
:
alert.addAction(UIAlertAction(title: "", style: .default) { [foo] _ in
print(foo)
})
Upvotes: 2