16

正如 Apple 在“The Swift Programming Language”中所说,我们似乎应该unownedweak任何时候都更喜欢:

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

来自本页的“弱引用和无主引用”部分

我确实知道这两者之间的区别。但我很好奇有什么好的理由更喜欢 unownedweak吗?我认为weak它更安全,我们总是可以编写[weak obj]一个可选的绑定检查,而不用考虑obj.

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

4

2 回答 2

26

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

class SomeOtherClass {
    weak var weakProperty: SomeClass?
}

weakProperty如果可以nil在实例SomeOtherClass仍然存在的情况下成为可能,这很好,我们想在使用它之前检查它(委托就是这样一个例子)。但是,如果某些引用在逻辑上不应该存在nil,而我们仍想阻止保留循环怎么办?在 Objective-C 中,任何对象引用都可以nil(并且消息传递nil总是默默地失败)所以没有两难选择,我们总是使用weak. 但是 Swift 根本没有 nilable 引用。我们将可选项用于在语义上可能缺乏价值的东西。但是我们不应该被迫将可选项用于必须始终具有价值的东西,只是为了能够打破保留循环。这种做法将违背可选的预期语义。

这就是unowned进来的地方。它有两种口味 -unowned(safe)unowned(unsafe)。后者是危险的,它assignunsafe_unretainedObjective-C 等价。但是前者是默认的(至少在调试时;不确定他们是否unowned(unsafe)在发布版本中对其进行了优化),如果引用的对象被过早地释放,它将可靠地使您的应用程序崩溃。当然,如果出现问题,您的应用程序会崩溃,但这比静默失败更容易调试。它应该只在你真正想要的时候默默地失败(在这种情况下你会使用weak

于 2014-08-19T12:54:57.090 回答
1

Swift 强、弱、无主引用

【Objective-C 属性属性】

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

Strong reference- 默认设置,在线性关系中使用这种类型是安全的(没有循环)

Retain cycle- 这是一种情况,每个对象都对彼此有很强的引用

打破Retain cycle:weakunowned. 它们都不会将对象的保留计数增加+1,并且具有下一个差异

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

weak var delegate: <Type>?

一般的

unowned- 当引用对象被释放(是nil)时,unowned 不会变成a 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_unretainedObjective-C. 它是一种ARC不处理的直接内存访问。它会产生意想不到的行为,而不仅仅是一些崩溃。它有更好的性能

EXC_BAD_ACCESS

[EXC_BAD_ACCESS]
[关闭示例]

于 2020-04-03T21:14:08.703 回答