[正如苹果在“ The Swift Programming Language”中所说,似乎我们应该尽可能地选择unowned
而不是weak
:
如果捕获的引用永远不会为零,则应始终将其捕获为未拥有的引用,而不是弱引用。
摘自this page的“弱引用和无主引用”部分
我确实知道这两者之间的区别。但是我很好奇,是否有充分的理由偏爱unowned
而不是weak
?我认为weak
更安全,我们可以随时编写[weak obj]
和可选的绑定检查,而无需考虑obj
存在的可能性。
它与性能方面的考虑有关还是我错过了?还是一直使用weak
而不是unowned
完全可以吗?
弱引用一旦被指向的对象被释放,就会自动设置为'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'
)
ARC
-Automatic Reference Counting
是一种管理内存的机制,适用于reference
类型[About]。仅当对象上有0个引用时,该对象才被释放。
Strong reference
-默认设置,可以安全地在线性关系中使用此类型(没有循环)
[Retain cycle
-当每个对象之间都有很强的引用时]
中断Retain cycle
:weak
和unowned
。两者都不会使对象的保留计数增加+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)
由可以创建UnsafePointer
的dangling pointer
操作。 __unsafe_unretained
中的Objective-C
。它是ARC
无法处理的直接内存访问。它会产生意外的行为,而不仅仅是崩溃。性能更好
EXC_BAD_ACCESS