Как "усилить" опциональную функцию самозащиты в Swift 2.0
Здесь есть аналогичный вопрос о том, как weakify
/strongify
self, на который отвечает, но мне интересно, как использовать "я" без права -drifting, вызванный if let
:
Welcome to Apple Swift version 2.0 (700.0.59 700.0.72). Type :help for assistance.
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. }
repl.swift:6:19: error: pattern matching in a condition requires the 'case' keyword
guard let self = self else { throw NSError(domain: "I was destroyed!", code: 1, userInfo: nil) }
^
case
repl.swift:6:23: error: binary operator '~=' cannot be applied to two 'Foo?' operands
guard let self = self else { throw NSError(domain: "I was destroyed!", code: 1, userInfo: nil) }
Ответы
Ответ 1
Вы можете затенять self
; вам просто нужны обратные сигналы, чтобы указать, что "вы знаете, что делаете". Например:
foo.doSomethingAsyncWithBar(bar) { [weak self] result in
guard let `self` = self else { return }
self.receivedResult(result)
}
Или в вашем примере:
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. }
Ответ 2
Потому что guard let `self` = self
является ошибкой компилятора, как указано Крисом Латтнером. Я попытался бы избежать этого. В вашем примере вы можете использовать простое дополнительное связывание:
return { [weak self] in
self?.doSomethingNonOptionalSelf()
}
Иногда вам может понадобиться использовать self в качестве параметра. В этом случае вы можете использовать flatMap
(по дополнительному типу).
{ [weak self] in
self.flatMap { $0.delegate?.tableView($0, didSelectRowAt: indexPath) }
}
Если вам нужно сделать что-то более сложное, вы можете использовать конструкцию if let
:
{ [weak self] in
if let strongSelf = self {
// Do something more complicated using strongSelf
}
}
или вы можете создать частный метод
{ [weak self] in
self?.doSomethingMoreComplicated()
}
...
private func doSomethingMoreComplicated() {
// Do something more complicated
}