强制解包在同一行代码中可选访问的变量是否安全? [英] Is it safe to force unwrap variables that have been optionally accessed in the same line of code?

查看:41
本文介绍了强制解包在同一行代码中可选访问的变量是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

总是安全吗?我在语句的开头访问了可选的 self,我个人认为如果 selfnil.这是真的?如果self 确实是nil,那么第二部分永远不会发生?并且永远不会发生 self 在这行代码中被nilled"的情况?

解决方案

可选链来自Swift 编程语言"给出以下例子:

<块引用>

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

后跟(强调):

<块引用>

在这个例子中,尝试设置 john.residence 的地址属性将失败,因为 john.residence 当前为零.

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

适用于您的案例:在

self?.variable = self!.otherVariable

如果selfnil,则评估右侧.因此,您的问题的答案

<块引用>

如果 self 确实是 nil,那么第二部分永远不会发生?

是是".关于第二个问题

<块引用>

在这行代码中,self 永远不会被nilled"?

我最初的假设是一旦self被确定为!= nil,对 self! 的强引用在整个评估过程中保持声明,以免发生这种情况.但是(正如@Hamish 指出的那样),这不能保证.Apple 工程师 Joe Groff 在确认操作顺序中写道Swift 论坛:

<块引用>

这不能保证.发布可能会被优化为在此之前发生,直到最后一次正式使用强引用之后的任何时间点.由于为评估左侧weakProperty?.variable而加载的强引用在之后没有被使用,因此没有任何东西使其保持活动状态,因此可以立即释放它.
如果变量的 getter 中有任何副作用导致 weakProperty 引用的对象被释放,清除弱引用,那么这将导致强制解包正确的一面失败.您应该使用 if let 来测试弱引用,并引用 if let

绑定的强引用

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

Is this always safe? I access the optional self in the beginning of the statement, and personally I assume that the second part of this statement will never be executed if self is nil. Is this true? If self indeed is nil, the second part will never happen? And it will never happen that self could be 'nilled' during this single line of code?

解决方案

Optional Chaining from "The Swift Programming Language" gives the following example:

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

followed by (emphasis added):

In this example, the attempt to set the address property of john.residence will fail, because john.residence is currently nil.

The assignment is part of the optional chaining, which means none of the code on the right hand side of the = operator is evaluated.

Applied to your case: In

self?.variable = self!.otherVariable

the right-hand side is not evaluated if self is nil. Therefore the answer to your question

If self indeed is nil, the second part will never happen?

is "yes". With regard to the second question

And it will never happen that self could be 'nilled' during this single line of code?

My original assumption was that once self has been determined to be != nil, a strong reference to self! is held throughout the evaluation of the statement, so that this can not happen. However (as @Hamish pointed out), this is not guaranteed. Apple engineer Joe Groff writes at Confirming order of operations in the Swift forum:

This isn't guaranteed. Releases may be optimized to happen earlier than this, to any point after the last formal use of the strong reference. Since the strong reference loaded in order to evaluate the left-hand side weakProperty?.variable is not used afterward, there is nothing keeping it alive, so it could be immediately released.
If there are any side effects in the getter for variable that cause the object referenced by weakProperty to be deallocated, nil-ing out the weak reference, then that would cause the force-unwrap on the right side to fail. You should use if let to test the weak reference, and reference the strong reference bound by the if let

这篇关于强制解包在同一行代码中可选访问的变量是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆