一尘不染

强制解开在同一行代码中已选择访问的变量是否安全?

swift

someFunction(completion: { [weak self] in
    self?.variable = self!.otherVariable
})

总是 安全吗?我self在语句的开头访问可选内容,并且我个人认为如果selfis
,则该语句的第二部分将永远不会执行nil。这是真的?如果self确实是nil,第二部分将永远不会发生?self在这单行代码中,它永远不会被“消灭”吗?


阅读 228

收藏
2020-07-07

共1个答案

一尘不染


来自“
Swift编程语言”的可选链接给出了以下示例:

 let john = Person()
 // ...
 let someAddress = Address()
 // ...
 john.residence?.address = someAddress

其次(强调):

在此示例中,尝试设置john.residence的地址属性将失败,因为john.residence当前为nil。

赋值是可选链接的一部分,这意味着 =运算符右侧的任何代码都不会被评估。

适用于您的案例:

self?.variable = self!.otherVariable

如果是, 则不 评估右侧。因此,您问题的答案self``nil

如果自我确实为零,那么第二部分永远不会发生?

是是的”。关于第二个问题

在这单行代码中,自我可能永远不会被“刺死”吗?

我最初的 假设 是,一旦self确定为!= nilself!则在评估语句的整个过程中都会使用强烈引用,因此不会发生这种情况。但是(如@Hamish所指出的),这不能保证。苹果工程师Joe
Groff 在Swift论坛中的确认操作顺序中写道:

这不能保证。可以对发布进行优化,使发布早于此,直到强引用最后一次正式使用之后的任何时候。由于此后weakProperty?.variable未使用为评估左侧而加载的强参考,因此没有任何东西可以使它存活,因此可以立即释放它。
如果getter变量中有任何副作用导致weakProperty取消引用的对象, 从而弱引用无效,那么这将导致右侧的强制展开失败。
您应使用if来测试弱引用,并引用由if let

2020-07-07