There\'s a similar question about how to weakify
/strongify
self, which is answered, but I\'m wondering how to use \"self\" without rightward-drifti
As of Swift 4.2 you no longer need to use self with backticks (compiler bug) or weird variable names like strongSelf
. You can use guard let self = self else { return }
to unwrap weak self
:
class Example {
var closure: (() -> Void)?
init() {
self.closure = { [weak self] in
guard let self = self else {
return
}
// ...
}
}
}
You can read more about it in the Swift evolution proposal.
You can shadow self
; you just need backticks to indicate that "you know what you're doing". For example:
foo.doSomethingAsyncWithBar(bar) { [weak self] result in
guard let `self` = self else { return }
self.receivedResult(result)
}
Or, in your example:
2> import Foundation
3> class Foo {
4. func guardOptSelf() -> () throws -> Void {
5. return { [weak self] in
6. guard let `self` = self else { throw NSError(domain: "I was destroyed!", code: 1, userInfo: nil) }
7. self.doSomethingNonOptionalSelf()
8. }
9. }
10. }
Since Swift 4.2 you can use the following syntax:
{ [weak self] in
guard let self = self else { return }
// self is not an optional anymore, it is held strongly
}
For more see the Swift evolution proposal SE-0079.
Sometimes other approaches than using guard let
might be useful as well (e.g. shorter or more readable). See also the following section, just replace strongSelf
with self
in few examples.
Because guard let `self` = self
is a compiler bug as stated by Chris Lattner I would try to avoid it. In your example you can use just simple optional chaining:
return { [weak self] in
self?.doSomethingNonOptionalSelf()
}
Sometimes you might need to use self as a parameter. In such case you can use flatMap
(on an optional type):
{ [weak self] in
self.flatMap { $0.delegate?.tableView($0, didSelectRowAt: indexPath) }
}
In case you need to do something more complicated you can use if let
construct:
{ [weak self] in
if let strongSelf = self {
// Do something more complicated using strongSelf
}
}
or guard let
construct:
{ [weak self] in
guard let strongSelf = self else { return }
// Do something more complicated using strongSelf
}
or you can create a private method:
{ [weak self] in
self?.doSomethingMoreComplicated()
}
...
private func doSomethingMoreComplicated() {
// Do something more complicated
}