swift2 如何在Swift 2.0中“强化”可选的自使用防护

wlwcrazw  于 2022-11-06  发布在  Swift
关注(0)|答案(3)|浏览(210)

有一个similar question是关于如何weakify/strongify self的,这个问题已经得到了回答,但是我想知道如何使用“self”而不使用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) }
jaql4c8m

jaql4c8m1#

你可以跟踪他们你只需要用反勾号来表示“你知道你在做什么”。例如:

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. }
ajsxfq5m

ajsxfq5m2#

雨燕4.2

从Swift 4.2开始,您可以使用以下语法:

{ [weak self] in
    guard let self = self else { return }

    // self is not an optional anymore, it is held strongly
}

欲了解更多信息,请参阅Swift演进建议SE-0079
有时使用guard let以外的其他方法也可能有用(例如更短或更易读)。另请参见下一节,只是在几个示例中将strongSelf替换为self

Swift 4.1及更早版本

因为guard letself= 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结构:

{ [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
}
fwzugrvs

fwzugrvs3#

从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中了解更多信息。

相关问题