强制解包在同一行代码中可选访问的变量是否安全? [英] Is it safe to force unwrap variables that have been optionally accessed in the same line of code?
问题描述
someFunction(completion: { [weak self] inself?.variable = self!.otherVariable})
这总是安全吗?我在语句的开头访问了可选的 self
,我个人认为如果 self
是 nil代码>.这是真的?如果
self
确实是nil
,那么第二部分永远不会发生?并且永远不会发生 self
在这行代码中被nilled"的情况?
可选链来自Swift 编程语言"给出以下例子:
<块引用> let john = Person()//...让 someAddress = Address()//...john.residence?.address = someAddress
后跟(强调):
<块引用>在这个例子中,尝试设置 john.residence 的地址属性将失败,因为 john.residence 当前为零.
赋值是可选链的一部分,这意味着不会评估 = 运算符右侧的任何代码.
适用于您的案例:在
self?.variable = self!.otherVariable
如果self
是nil
,则不评估右侧.因此,您的问题的答案
如果 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 byweakProperty
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 theif let
这篇关于强制解包在同一行代码中可选访问的变量是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!