无人与弱者。为什么我们应该首选无主?

问题描述 投票:12回答:2

[正如苹果在“ The Swift Programming Language”中所说,似乎我们应该尽可能地选择unowned而不是weak

如果捕获的引用永远不会为零,则应始终将其捕获为未拥有的引用,而不是弱引用。

摘自this page的“弱引用和无主引用”部分

我确实知道这两者之间的区别。但是我很好奇,是否有充分的理由偏爱unowned而不是weak?我认为weak更安全,我们可以随时编写[weak obj]和可选的绑定检查,而无需考虑obj存在的可能性。

它与性能方面的考虑有关还是我错过了?还是一直使用weak而不是unowned完全可以吗?

memory-management swift
2个回答
18
投票

弱引用一旦被指向的对象被释放,就会自动设置为'nil'。为了在Swift中实现这一点,必须将其声明为'var'和可选:

class SomeOtherClass {
    weak var weakProperty: SomeClass?
}

[如果在'weakProperty'的实例仍处于活动状态时'nil'可以变为'SomeOtherClass',这很好,我们想在使用它之前对其进行检查(代理就是这样的示例)。但是,如果某些引用在逻辑上永远不应该是'nil',而我们仍然想防止保留周期怎么办?在Objective-C中,任何对象引用都可以为'nil'(并且消息传递'nil'总是无提示失败),因此没有任何难题,我们始终使用'weak'。但是Swift根本没有零引用。对于语义上可能缺乏价值的东西,我们使用可选的东西。但是,我们不应被迫对必须始终具有价值的东西使用可选参数,以使其能够打破保留周期。这种做法将违反可选的预期语义。这就是'unowned'的来源。它有两种风格-'unowned(safe)''unowned(unsafe)'。后者很危险,它等效于Objective-C的'assign''unsafe_unretained'。但是前者是默认值(至少在调试时,不确定在发布版本中是否将其优化为“ unown(unsafe)”),如果所引用的对象过早地被释放,它将可靠地使我们的应用程序崩溃。当然,如果出现问题,我们的应用程序将崩溃,但是调试比静默失败要容易得多。仅当我们确实需要它时,它才应该静默地失败(在这种情况下,我们将使用'weak'


0
投票

ARC-Automatic Reference Counting是一种管理内存的机制,适用于reference类型[About]。仅当对象上有0个引用时,该对象才被释放。

Strong reference-默认设置,可以安全地在线性关系中使用此类型(没有循环)

[Retain cycle-当每个对象之间都有很强的引用时]

中断Retain cycleweakunowned。两者都不会使对象的保留计数增加+1,并且具有下一个差异

Weak reference-释放引用对象(为nil)时,ARC也将weak引用设置为nil。这就是为什么weak引用是变量var(不能是常量let),也就是为什么它是optional

unowned-释放引用对象(为nil)时,unowned 成为nil,因为ARC未设置。这就是unowned参考是非可选

的原因

safe unowned-如果释放了runtime safety check引用,则使用unowned引发异常。

Fatal error: Attempted to read an unowned reference but object 0x7fa5dad3f0f0 was already deallocated

unowned(unsafe)由可以创建UnsafePointerdangling pointer操作。 __unsafe_unretained中的Objective-C。它是ARC无法处理的直接内存访问。它会产生意外的行为,而不仅仅是崩溃。性能更好

EXC_BAD_ACCESS

Closure sample

© www.soinside.com 2019 - 2024. All rights reserved.