在 Swift 中,如果我有一个捕获 [weak self] 的闭包,在闭包开始时解包可选的 self 是一种好习惯吗?
In Swift, if I have a closure capturing [weak self], is it good practice to unwrap the optional self at the beginning of the closure?
我正在为 macOS 应用程序使用 Swift,Xcode 是 12.5.1。假设我有以下代码:
func performAsyncTask(completion: { [weak self] (error: Error?) in
self?.someProperty = 0.0
self?.someOtherProperty = 0.0
// Other similar statements follow
})
改成:
是不是不错的选择
func performAsyncTask(completion: { [weak self] (error: Error?) in
guard let self = self else { return }
self.someProperty = 0.0
self.someOtherProperty = 0.0
// Other similar statements follow
})
我相信第一个实现更好,因为 self 可能在 语句之间变成 nil,所以在开始时解包可能不太干净。我希望专家能给我指明正确的方向。感谢您的关注。
I believe that the first implementation is better because self could become nil between the statements
这就是 second 实施实际上更好的原因!如果 self
在第一个语句中不为 nil,则第一个语句使得 self
不能 在语句之间变为 nil
。它为块的其余部分保留了 self
。这就是所谓的“强弱之舞”。
guard let self = self else { return }
// ^^^^ this self is _strong_, not weak; it retains self
出于与您给出的相同原因,我会以另一种方式争论(在您的第一个版本中,self
可以在您的关闭代码 运行s 的任何时候被释放)。
如果闭包 运行 位于与保留 self 的代码不同的线程上,则对象可能会在引用 self?
的不同语句之间变为 nil。 (这不太可能,但有可能。)如果你的闭包代码做的事情比仅仅将属性分配给 self 更复杂,那么在它中间释放 self
可能会使整个闭包变得毫无意义,甚至使其失败. (假设您正在进行图像处理,而图像在处理过程中消失了。)
在第二个版本中,guard let self = self
语句在闭包范围内创建对 self 的强引用,这意味着 self
引用的对象在闭包完成之前不会被释放.
我宁愿知道 self
是否仍然存在于闭包的开头,然后 运行 完整的闭包代码,而不是必须防御性地编写我的闭包代码以继续检查“有自我被释放了?现在怎么样?现在?好的,现在怎么样?
就编码风格和可读性而言,不得不不断地处理可选的 chaining/binding/nil 合并是一件痛苦的事情,并且会使您的代码更难理解
我正在为 macOS 应用程序使用 Swift,Xcode 是 12.5.1。假设我有以下代码:
func performAsyncTask(completion: { [weak self] (error: Error?) in
self?.someProperty = 0.0
self?.someOtherProperty = 0.0
// Other similar statements follow
})
改成:
是不是不错的选择func performAsyncTask(completion: { [weak self] (error: Error?) in
guard let self = self else { return }
self.someProperty = 0.0
self.someOtherProperty = 0.0
// Other similar statements follow
})
我相信第一个实现更好,因为 self 可能在 语句之间变成 nil,所以在开始时解包可能不太干净。我希望专家能给我指明正确的方向。感谢您的关注。
I believe that the first implementation is better because self could become nil between the statements
这就是 second 实施实际上更好的原因!如果 self
在第一个语句中不为 nil,则第一个语句使得 self
不能 在语句之间变为 nil
。它为块的其余部分保留了 self
。这就是所谓的“强弱之舞”。
guard let self = self else { return }
// ^^^^ this self is _strong_, not weak; it retains self
出于与您给出的相同原因,我会以另一种方式争论(在您的第一个版本中,self
可以在您的关闭代码 运行s 的任何时候被释放)。
如果闭包 运行 位于与保留 self 的代码不同的线程上,则对象可能会在引用 self?
的不同语句之间变为 nil。 (这不太可能,但有可能。)如果你的闭包代码做的事情比仅仅将属性分配给 self 更复杂,那么在它中间释放 self
可能会使整个闭包变得毫无意义,甚至使其失败. (假设您正在进行图像处理,而图像在处理过程中消失了。)
在第二个版本中,guard let self = self
语句在闭包范围内创建对 self 的强引用,这意味着 self
引用的对象在闭包完成之前不会被释放.
我宁愿知道 self
是否仍然存在于闭包的开头,然后 运行 完整的闭包代码,而不是必须防御性地编写我的闭包代码以继续检查“有自我被释放了?现在怎么样?现在?好的,现在怎么样?
就编码风格和可读性而言,不得不不断地处理可选的 chaining/binding/nil 合并是一件痛苦的事情,并且会使您的代码更难理解