Swift。 unowned 相对于 weak 性能的(绝对)唯一特定优势是什么?

Swift. Is the (absolutely) sole specific advantage of unowned over weak, performance?

在Swift中,我们有正常的默认输入

我们有弱类型

我们有无主打字

(因此:推论:唯一一次你可以使用“unowned”的情况是你“绝对知道”该对象永远不会变为 nil。)

现在:

我觉得下面这句话,

绝对正确...

我的意思是,真的,真的,绝对,深入到可能的最深层次的哲学问题 true...

“unowned 和 weak 之间的唯一区别是性能。因为 unowned 没有检查,所以速度更快。绝对没有其他区别。”

因此逻辑推论:

绝对,没有理由使用 unowned,除非需要比 weak 更高的性能。”

{除此之外 - 我能想到的唯一其他区别是在自我记录的意义上。如果我使用 unowned,它会提示我的开发人员了解某些事情;让我们暂时搁置这个问题。)

所以我的问题很直截了当,非常准确,非常具体:上面的粗体句子是“真实”(在“完全,非常,壮观”的真实意义上是真实的)。

加粗的句子不正确

Weak是可选的,可以随时设置。

Unowned 是 non-optional 但可以为零。如果发生这种情况并且您称之为您的应用程序崩溃。必须在初始化时设置。

正如作者所说,另一个区别是性能。 Unowned 不做任何检查并且比 weak.

稍微快一点

更能体现类.

之间的关系

您可以查看此 SO 问题以获取更多详细信息:What is the difference between a weak reference and an unowned reference?

我同意 Yannick 的观点。你的大胆陈述是不正确的。无主引用 必须 在其生命周期内有效。在 -Ounchecked 程序中,未能保持此前提条件是未定义的行为。我不是说 "it crashes." 我是说它不是 well-formed 程序;它的作用是不确定的。即使在 -Ounchecked.

下,弱引用也不会因其释放而产生未定义的行为

Using unowned 是程序员声明引用将在其整个生命周期内有效。 Type! 甚至都没有断言。 ! 类型只是断言引用在访问时有效。这就是为什么你不能在 unowned 上测试 x == nil 的原因。它不是可选的。它不是 "optional in disguise"(比如 Type!)。它必须始终有效。

Unlike a weak reference, however, an unowned reference is used when the other instance has the same lifetime or a longer lifetime. ... An unowned reference is expected to always have a value. —— [The Swift Programming Language]

所以你的 "deepest possible philosophical," unowned 包含一个在 weak 中不存在的先决条件。这个先决条件存在于程序之外,必须由程序员而不是编译器来证明,以确保 well-formed 程序。

至于是否有使用 unowned 的理由,如果我们采取绝对立场(如您的问题),那当然有。在已知前提条件为真的情况下,它是最严格的类型。 weak 是比 unowned 弱的类型;它表示更少的先决条件。好的类型理论鼓励我们尽可能使用最强的(限制性最强;合法值最少)类型,unowned 是比 weak.

更强的类型

在 non-absolutist ("practical") 意义上,选择更强类型的结果是更简单的代码。当你使用 weak 时,你必须不断地 re-assert 每次使用它时它不是 nil 的前提条件并处理它的情况(可能插入 fatalError 这只是通过更多工作重塑 unowned)。使用 unowned 可让您断言此前提条件一次。这会创建更简单、更正确的代码。我从来没有使用 unowned 来提高速度。我一直用它来避免在代码中一遍又一遍地回答 "but what if it's nil?",它永远不能为 nil。

来自 swift 文档

"Swift also provides unsafe unowned references for cases where you need to disable runtime safety checks—for example, for performance reasons. As with all unsafe operations, you take on the responsibility for checking that code for safety.

You indicate an unsafe unowned reference by writing unowned(unsafe). If you try to access an unsafe unowned reference after the instance that it refers to is deallocated, your program will try to access the memory location where the instance used to be, which is an unsafe operation."

似乎只有当您使用 unowned(unsafe) 时才能提高性能,默认情况下我们使用 unowed(safe)。

This is from one of the answer

unowned(safe) is a non-owning reference that asserts on access that the object is still alive. It's sort of like a weak optional reference that's implicitly unwrapped with x! every time it's accessed. unowned(unsafe) is like __unsafe_unretained in ARC—it's a non-owning reference, but there's no runtime check that the object is still alive on access, so dangling references will reach into garbage memory. unowned is always a synonym for unowned(safe) currently, but the intent is that it will be optimized to unowned(unsafe) in -Ofast builds when runtime checks are disabled.