弱引用和无主引用有什么区别? [英] What is the difference between a weak reference and an unowned reference?

查看:33
本文介绍了弱引用和无主引用有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

斯威夫特有:

  • 强有力的参考
  • 弱引用
  • 无主引用

无主引用与弱引用有何不同?

How is an unowned reference different from a weak reference?

什么时候使用无主引用是安全的?

When is it safe to use an unowned reference?

无主引用是否存在安全风险,例如 C/C++ 中的悬垂指针?

Are unowned references a security risk like dangling pointers in C/C++?

推荐答案

weakunowned 引用都不会创建 strong 保留引用的对象(也就是它们不会增加保留计数以防止 ARC 取消分配引用的对象).

Both weak and unowned references do not create a strong hold on the referred object (a.k.a. they don't increase the retain count in order to prevent ARC from deallocating the referred object).

但为什么是两个关键字?这种区别与 Optional 类型是 Swift 语言内置的事实有关.长话短说:可选类型提供内存安全(这与 Swift 的构造函数规则 - 为了提供这种好处而严格).

But why two keywords? This distinction has to do with the fact that Optional types are built-in the Swift language. Long story short about them: optional types offer memory safety (this works beautifully with Swift's constructor rules - which are strict in order to provide this benefit).

weak 引用允许它变成 nil(当引用的对象被释放时这会自动发生),因此你的属性的类型必须是可选的 -因此,作为程序员,您有义务在使用之前对其进行检查(基本上编译器会强迫您尽可能多地编写安全代码).

A weak reference allows the possibility of it to become nil (this happens automatically when the referenced object is deallocated), therefore the type of your property must be optional - so you, as a programmer, are obligated to check it before you use it (basically the compiler forces you, as much as it can, to write safe code).

unowned 引用假定它在其生命周期内永远不会变为 nil.初始化期间必须设置无主引用 - 这意味着该引用将被定义为非可选类型,无需检查即可安全使用.如果被引用的对象以某种方式被解除分配,那么当使用无主引用时应用程序将崩溃.

An unowned reference presumes that it will never become nil during its lifetime. An unowned reference must be set during initialization - this means that the reference will be defined as a non-optional type that can be used safely without checks. If somehow the object being referred to is deallocated, then the app will crash when the unowned reference is used.

来自 Apple 文档:

只要该引用有效,就使用弱引用在其生命周期中的某个时刻为零.相反,使用无主当您知道参考一旦它就永远不会为零时的参考初始化时已设置.

Use a weak reference whenever it is valid for that reference to become nil at some point during its lifetime. Conversely, use an unowned reference when you know that the reference will never be nil once it has been set during initialization.

在文档中,有一些示例讨论了保留循环以及如何打破它们.所有这些示例均摘自文档.

In the docs, there are some examples that discuss retain cycles and how to break them. All these examples are extracted from the docs.

weak 关键字示例:

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
}
 
class Apartment {
    let number: Int
    init(number: Int) { self.number = number }
    weak var tenant: Person?
}

现在,对于一些 ASCII 艺术(你应该去查看文档 - 他们有漂亮的图表):

And now, for some ASCII art (you should go see the docs - they have pretty diagrams):

Person ===(strong)==> Apartment
Person <==(weak)===== Apartment

PersonApartment 示例显示了一种情况,其中两个属性都允许为 nil,有可能导致强引用循环.这种情况最好用弱引用来解决.两个实体都可以存在而不严格依赖另一个.

The Person and Apartment example shows a situation where two properties, both of which are allowed to be nil, have the potential to cause a strong reference cycle. This scenario is best resolved with a weak reference. Both entities can exist without having a strict dependency upon the other.

unowned 关键字示例:

class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) { self.name = name }
}
 
class CreditCard {
    let number: UInt64
    unowned let customer: Customer
    init(number: UInt64, customer: Customer) { self.number = number; self.customer = customer }
}

在本例中,Customer 可能有也可能没有 CreditCard,但 CreditCard 将始终Customer 相关联.为了表示这一点,Customer 类有一个可选的 card 属性,但 CreditCard 类有一个非可选(和无主)客户属性.

In this example, a Customer may or may not have a CreditCard, but a CreditCard will always be associated with a Customer. To represent this, the Customer class has an optional card property, but the CreditCard class has a non-optional (and unowned) customer property.

Customer ===(strong)==> CreditCard
Customer <==(unowned)== CreditCard

CustomerCreditCard 示例显示了一种情况,其中一个允许为 nil 的属性和另一个不能为 nil 的属性有可能导致强引用循环.这种情况最好使用无主引用来解决.

The Customer and CreditCard example shows a situation where one property that is allowed to be nil and another property that cannot be nil has the potential to cause a strong reference cycle. This scenario is best resolved with an unowned reference.

来自 Apple 的说明:

Note from Apple:

弱引用必须声明为变量,以表明它们的值可以在运行时改变.弱引用不能声明为常数.

Weak references must be declared as variables, to indicate that their value can change at runtime. A weak reference cannot be declared as a constant.

还有第三种情况,即两个属性都应该始终有一个值,并且一旦初始化完成,两个属性都不应该为零.

There is also a third scenario when both properties should always have a value, and neither property should ever be nil once initialization is complete.

在使用闭包时,还有一些经典的保留循环场景需要避免.

And there are also the classic retain cycle scenarios to avoid when working with closures.

为此,我鼓励您访问 Apple 文档,或阅读本书.

For this, I encourage you to visit the Apple docs, or read the book.

这篇关于弱引用和无主引用有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆