【发布时间】: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的调用,那么如果self是nil,则更容易防范和提早退出。 -
Zoul 是正确的。如果多次调用
self,并且在关闭期间超出范围,那么您最终可能会出现意外状态。还有一个守卫向下一个开发人员表明此功能需要self才能工作,如果在没有self的情况下运行闭包没有意义,则应使用守卫进行检查。 -
为什么不简单的可选链
self?.someFunction()?
标签: swift