迅速。无主的(绝对)唯一的特定优势是弱性能吗?
Posted
技术标签:
【中文标题】迅速。无主的(绝对)唯一的特定优势是弱性能吗?【英文标题】:Swift. Is the (absolutely) sole specific advantage of unowned over weak, performance? 【发布时间】:2017-01-24 14:25:13 【问题描述】:在 Swift 中,我们有正常的默认类型
对象根本不可能变成 nil。我们的打字很弱
对象可以变为 nil。如果对象变成 nil,你的指针会自动变成 nil,所以你知道对象变成了 nil我们有无主的打字
对象可以变为 nil。如果对象变为 nil,则指针不会发生任何事情 - 如果您尝试使用它,您会被搞砸(因此:推论:你可以使用“unowned”的唯一一次是如果你“绝对知道”该对象将永远不会变为 nil。)
现在:
在我看来,下面这句话,
是绝对真的...
我的意思是,真的,真的,绝对,直到最深层次的哲学问题真的......
“unowned 和weak 的唯一区别是性能。由于unowned 没有检查,所以速度更快。绝对没有其他区别。”
因此逻辑推论:
“有,绝对,没有理由使用 unowned,除非需要额外的弱性能。”
除此之外 - 我能想到的唯一其他区别是在自我记录的意义上。如果我使用 unowned,它会提示我的其他开发人员注意某些事情;让我们暂时搁置这个问题。)
所以我的问题是直截了当、非常准确、非常具体的:“真实”上方的粗体句子是真实的吗(在“完全、非常、壮观”的真实意义上)。
【问题讨论】:
不必每次都打开包装,这不是很大的不同吗? 对,无主变量不是可选的,因此您可以避免麻烦。 @JamesP - 这可能是一个突出的点;也许一个有启发性的例子的答案可能是有序的? 【参考方案1】:我同意亚尼克的观点。你的粗体陈述是不正确的。无主引用必须在其生命周期内有效。在-Ounchecked
程序中,未能维护此前提条件是未定义的行为。我的意思不是“它崩溃了”。我的意思是它不是一个格式良好的程序。它的作用是不确定的。弱引用由于其发布而无法生成未定义的行为,即使在-Ounchecked
下也是如此。
使用unowned
是程序员声明的引用将在其整个生命周期内有效。这甚至不是Type!
断言的东西。 !
类型只是断言引用在访问时将是有效的。这就是为什么您不能在无主对象上测试 x == nil
的原因。这不是可选的。它不是“变相可选”(如Type!
)。它必须始终有效。
然而,与弱引用不同的是,当另一个实例具有相同的生命周期或更长的生命周期时,将使用无主引用。 ... 一个无主引用应该总是有一个值。 —— [The Swift Programming Language]
因此,对于您的“最深层次的哲学”,无主包括一个不存在于弱中的先决条件。这个前提条件存在于程序之外,必须由程序员而不是编译器证明,以确保程序结构良好。
是否有理由使用unowned
,如果我们采取绝对立场(如您的问题),那肯定是有理由的。在已知前提条件为真的情况下,它是最严格的类型。 weak
是比unowned
弱的类型;它表达的先决条件较少。好的类型理论鼓励我们尽可能使用最强(限制性最强;合法值最少)的类型,unowned
是比weak
更强的类型。
在非绝对主义(“实用”)意义上,选择更强类型的结果是更简单的代码。当您使用weak
时,您必须在每次使用它时不断重新断言它不是nil
的前提条件并处理它的情况(可能插入fatalError
,它只是通过更多工作重新发明unowned
)。使用unowned
可以让您一次性断言此前提条件。这会创建更简单、更正确的代码。我从来没有使用unowned
来提高速度。我一直用它来避免一遍又一遍地回答“但如果它是零怎么办?”在代码中它绝不能为零。
【讨论】:
这是一个深刻的想法,无主是更强 ...很好。太棒了。 “我一直使用它来避免一遍又一遍地回答“但是如果它是 nil 怎么办?”在代码中它决不能是 nil。我认为,这很有见地,真正回答了问题的“核心”。【参考方案2】:粗体句子不正确。
Weak
是可选的,可以随时设置。
Unowned
是非可选的,但可以为零。如果发生这种情况并且你称之为你的应用程序崩溃。必须在初始化时设置。
正如作者所说,另一个区别是性能。 Unowned
不做任何检查,比weak
稍快。
更好地展示了类之间的关系。
您可以查看此 SO 问题以了解更多详细信息:What is the difference between a weak reference and an unowned reference?
【讨论】:
Unowned
表面上是非可选的,但它可能会突然变为 nil(或无效指针,更好的措辞),如果使用不当会破坏您的应用程序。
是的,但我不想在这里详细介绍。发布的链接更详细地介绍了这一点,而且作者自己也说过。
嘿@Yannick - 谢谢你;我倾向于说“但除此之外还有什么不同吗”:)这可能不符合我的问题的精神:)
嗨@user28434 - 是的,当然:这就是问题的重点。显然无主可以通过悬空下地狱:我的问题,除了纯粹的性能之外还有任何优势吗?
@JoeBlow,性能提升很小 + 非可选“接口”,例如 T!
与 T?
。【参考方案3】:
来自快速文档
"Swift 还为您在以下情况下提供了不安全的无主引用 需要禁用运行时安全检查——例如,为了性能 原因。与所有不安全的操作一样,您承担责任 用于检查该代码的安全性。
你通过写 unowned(unsafe) 来表示一个不安全的无主引用。 如果您尝试在实例之后访问不安全的无主引用 它所指的已被释放,您的程序将尝试访问 实例曾经所在的内存位置,这是不安全的 操作。”
似乎只有当您准确地使用 unowned(unsafe) 并且默认情况下我们使用 unowed(safe) 时才能获得性能提升。
This is from one of the answer
unowned(safe) 是一个非拥有引用,它在访问时断言 对象还活着。这有点像一个弱可选参考 这是用 x 隐式展开的!每次访问它。 unowned(unsafe) 就像 ARC 中的 __unsafe_unretained — 它是非拥有的 参考,但没有运行时检查对象是否仍然存在 在访问时,因此悬空引用将进入垃圾内存。 当前,unowned 始终是 unowned(safe) 的同义词,但是 意图是它将在 -Ofast 中优化为无主(不安全) 在禁用运行时检查时构建。
【讨论】:
以上是关于迅速。无主的(绝对)唯一的特定优势是弱性能吗?的主要内容,如果未能解决你的问题,请参考以下文章