有similar question关于如何weakify
/ strongify
自我的问题,这已得到解答,但我想知道如何使用" self&#34 ;没有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) }
答案 0 :(得分:35)
你可以影子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. }
答案 1 :(得分:23)
从Swift 4.2开始,您可以使用以下语法:
{ [weak self] in
guard let self = self else { return }
// self is not an optional anymore, it is held strongly
}
有关更多信息,请参阅Swift evolution proposal SE-0079。
有时,除了使用guard let
之外的其他方法也可能有用(例如更短或更易读)。另请参阅以下部分,只需在少数示例中将strongSelf
替换为self
。
因为guard let `self` = self
是compiler bug as stated by Chris Lattner,我会尽量避免它。在您的示例中,您可以使用简单的可选链接:
return { [weak self] in
self?.doSomethingNonOptionalSelf()
}
有时您可能需要使用self作为参数。在这种情况下,您可以使用flatMap
(在可选类型上):
{ [weak self] in
self.flatMap { $0.delegate?.tableView($0, didSelectRowAt: indexPath) }
}
如果您需要做一些更复杂的事情,可以使用if let
construct:
{ [weak self] in
if let strongSelf = self {
// Do something more complicated using strongSelf
}
}
或guard let
构建:
{ [weak self] in
guard let strongSelf = self else { return }
// Do something more complicated using strongSelf
}
或者您可以创建一个私有方法:
{ [weak self] in
self?.doSomethingMoreComplicated()
}
...
private func doSomethingMoreComplicated() {
// Do something more complicated
}
答案 2 :(得分:6)
从Swift 4.2开始,您不再需要将self与反引号(编译器错误)或诸如strongSelf
之类的奇怪变量名一起使用。您可以使用guard let self = self else { return }
来解开weak self
:
class Example {
var closure: (() -> Void)?
init() {
self.closure = { [weak self] in
guard let self = self else {
return
}
// ...
}
}
}
您可以在Swift evolution proposal中了解更多信息。