无主与弱。为什么我们应该更喜欢无主?

时间:2014-08-19 07:20:00

标签: memory-management swift

正如Apple在“Swift编程语言”中所说,似乎我们应该尽可能选择unowned而不是weak

  

如果捕获的引用永远不会为nil,则应始终将其捕获为无主引用,而不是弱引用。

来自this page

上的“弱和无主参考”部分

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

是否与某些性能因素或我遗漏的内容有关?或者一直使用weak而不是unowned完全可以吗?

2 个答案:

答案 0 :(得分:16)

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

class SomeOtherClass {
    weak var weakProperty: SomeClass?
}

如果'weakProperty'的实例在'nil'的实例仍然存在且我们想要在使用之前检查'SomeOtherClass',那么这很好(委托是一个这样的例子)。但是,如果某些引用永远不应该是'nil'并且我们仍然希望阻止保留周期呢?在Objective-C中,任何对象引用都可以是'nil'(并且消息'nil'总是无声地失败)因此没有困境,我们总是使用'weak'。但斯威夫特根本没有可用的参考文献。我们使用选项来处理语义上缺乏价值的东西。但是我们不应该被迫使用选项来获得必须总是有价值的东西,只是为了能够打破一个保留周期。这种做法违背了期权的预期语义。 'unowned'来的地方。它有两种风格 - 'unowned(safe)''unowned(unsafe)'。后者是危险的,它等同于Objective-C中的'assign''unsafe_unretained'。但是前者是默认的(至少在调试时,不确定他们是否将其优化为发布版本中的“无主”(不安全)),如果引用的对象过早发生,将会可靠地崩溃我们的应用程序释放。当然,如果出现问题,我们的应用程序会崩溃,但调试比默认失败要容易得多。它应该只在我们真正想要的时候默默地失败(在这种情况下我们会使用'weak'

答案 1 :(得分:0)

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

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

Retain cycle-在这种情况下,每个对象之间都有很强的参照力

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

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

weak var delegate: <Type>?

常规

unowned-释放引用对象(为nil)时,unowned 不会成为nil,因为{{1 }}未设置。这就是为什么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

[Closure sample]