【问题标题】:Naming convention for weakly capturing self in a closure在闭包中弱捕获自我的命名约定
【发布时间】:2017-09-01 10:11:05
【问题描述】:

因为这会强烈捕获self,在执行闭包之前可能已经超出范围:

OperationQueue().addOperation {
    self.someFunction()
}

...在这些情况下,我弱捕获self 并使用警卫检查它是否仍在范围内。

我以前是这样写的:

OperationQueue().addOperation { [weak self] in
    guard let `self` = self else { return }

    self.someFunction()
}

但后来发现这仅由于编译器错误而起作用! https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007425.html

所以现在我使用不同的常量名称。阅读别人的代码我看到的最常见的是这样的:

OperationQueue().addOperation { [weak self] in
    guard let weakSelf = self else { return }

    weakSelf.someFunction()
}

但肯定self 比那个守卫强吗?所以应该这样写:

OperationQueue().addOperation { [weak self] in
    guard let strongSelf = self else { return }

    strongSelf.someFunction()
}

是否有最佳书写方式的约定?

-

更新 - 为什么可选链在这种情况下不是最佳选择:

如果在闭包中有多次对self 的调用,并且self 在闭包执行期间超出范围,那么您最终可能会出现意外状态。

还有一个守卫向下一位开发人员表明此功能需要self 才能工作,即没有self 运行闭包是没有意义的。

【问题讨论】:

  • 如果你使用 [weak self] 这意味着它可能在闭包中为零。为什么不直接调用somefunction like self?.someFunction
  • 这当然是一种选择,但如果在闭包中有更多对self 的调用,那么如果selfnil,则更容易防范和提早退出。
  • Zoul 是正确的。如果多次调用self,并且在关闭期间超出范围,那么您最终可能会出现意外状态。还有一个守卫向下一个开发人员表明此功能需要self 才能工作,如果在没有self 的情况下运行闭包没有意义,则应使用守卫进行检查。
  • 为什么不简单的可选链self?.someFunction()

标签: swift


【解决方案1】:

从 Swift 4.2 开始,您可以使用 guard let self = self else { return } 来解开 weak self。无需使用strongSelf`self` 编译器错误进行解包。
您可以在Swift evolution proposal 中阅读更多相关信息。

【讨论】:

    【解决方案2】:

    您可以通过这种方式在捕获列表中为您的对象命名:

    OperationQueue().addOperation { [weak object = self] in
        guard let object = object else { return }
        object.someFunction()
    }
    

    【讨论】:

    • 谢谢,这是一个我不知道的有趣功能,但它没有回答问题!
    猜你喜欢
    • 2021-01-20
    • 1970-01-01
    • 2015-03-16
    • 2013-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多