[英]When should i use capture list in closure, and when to use weak vs. unowned?
[英]unowned vs. weak. Why we should prefer unowned?
正如 Apple 在“The Swift Programming Language”中所说,似乎我们应该尽可能选择unowned
而非weak
:
如果捕获的引用永远不会变为 nil,则应始终将其捕获为无主引用,而不是弱引用。
来自本页的“弱引用和无主引用”部分
我确实知道这两者之间的区别。 但我很好奇有什么好的理由更喜欢unowned
不是weak
吗? 我认为weak
更安全,我们可以随时编写[weak obj]
和可选的绑定检查,而无需考虑obj
存在的可能性。
它与某些性能考虑或我错过的东西有关吗? 或者一直使用weak
而不是unowned
是完全可以的?
一旦弱引用指向的对象被释放,弱引用就会自动设置为nil
。 为了在 Swift 中实现这一点,必须将它们声明为var
和 optional:
class SomeOtherClass {
weak var weakProperty: SomeClass?
}
如果当SomeOtherClass
的实例仍然存在时, weakProperty
可以变为nil
并且我们想在使用它之前检查它(委托就是一个这样的例子),这很好。 但是,如果某个引用在逻辑上永远不应该为nil
并且我们仍然想要防止保留循环怎么办? 在 Objective-C 中,任何对象引用都可以是nil
(并且消息nil
总是默默地失败)所以没有两难,我们总是使用weak
。 但是 Swift 根本没有可空引用。 我们将可选项用于语义上可能缺乏价值的东西。 但是我们不应该被迫对必须始终有价值的东西使用可选项,只是为了能够打破保留循环。 这种做法会违背可选项的预期语义。
这就是unowned
用武之地。它有两种风格 - unowned(safe)
和unowned(unsafe)
。 后者是危险的,它等同于 Objective-C 中的assign
和unsafe_unretained
。 但是前者是默认的(至少在调试时;不确定他们是否在发布版本中将其优化为unowned(unsafe)
),如果引用的对象过早释放,将可靠地使您的应用程序崩溃。 当然,如果出现问题,您的应用程序会崩溃,但这比静默失败要容易得多。 它应该只在你真正想要的时候默默地失败(在这种情况下你会使用weak
)
ARC
- Automatic Reference Counting
是一种管理内存的机制,适用于reference
类型[About] 。 一个对象只有在有 0 个引用时才会被释放。
Strong reference
- 默认设置,在线性关系中使用这种类型是安全的(没有循环)
Retain cycle
- 这是每个 who 对象都对彼此有强引用的情况
打破Retain cycle
: weak
和unowned
。 它们都不会将对象的保留计数增加+1
,并且有下一个差异
Weak reference
- 当引用对象被释放(为nil
)时, ARC
也会将weak
引用设置为nil
。 这就是为什么weak
引用是一个变量var
(不能是一个常量let
) [var vs let]这就是为什么它是一个optional
weak var delegate: <Type>?
一般的
unowned
- 当引用对象被释放(为nil
)时, unowned
不会变成nil
因为ARC
没有设置它。 这就是为什么unowned
引用是非可选的
无主(默认)
safe unowned
- 如果unowned
引用被释放,则使用runtime safety check
抛出异常。
Fatal error: Attempted to read an unowned reference but object 0x7fa5dad3f0f0 was already deallocated
无主(不安全)
UnsafePointer
unowned(unsafe)
由UnsafePointer
操作,可以创建一个dangling pointer
。 __unsafe_unretained
来自Objective-C
。 它是一种ARC
不处理的直接内存访问。 它会产生意想不到的行为,而不仅仅是一些崩溃。 它有更好的性能
EXC_BAD_ACCESS
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.