斯威夫特有:
无主引用与弱引用有何不同?
什么时候使用无主引用是安全的?
无主引用是否存在安全风险,例如C/C++ 中的悬空指针?
weak和引用都unowned不会在被引用对象上创建strong保留(也就是它们不会增加保留计数以防止 ARC 释放被引用对象)。
weak
unowned
strong
但是为什么有两个关键字呢?这种区别与OptionalSwift 语言中内置的类型有关。长话短说:可选类型提供内存安全(这与Swift 的构造函数规则完美配合——为了提供这种好处,这些规则非常严格)。
Optional
weak引用允许它成为可能(这在nil被引用的对象被释放时自动发生),因此您的属性类型必须是可选的 - 所以作为程序员,您有义务在使用它之前检查它(基本上是编译器尽可能地强迫你编写安全代码)。
nil
unowned参考假定它在其生命周期内永远不会变成nil。必须在初始化期间设置无主引用——这意味着该引用将被定义为非可选类型,无需检查即可安全使用。如果以某种方式被引用的对象被释放,那么当使用无主引用时应用程序将崩溃。
来自苹果文档:
只要该引用在其生命周期中的某个时间点变为 nil 有效,就使用弱引用。相反,当您知道一旦在初始化期间设置引用将永远不会为零时,请使用无主引用。
在文档中,有一些示例讨论了保留周期以及如何打破它们。所有这些示例都是从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 艺术(你应该去看看文档——他们有漂亮的图表):
Person ===(strong)==> Apartment Person <==(weak)===== Apartment
PersonandApartment示例显示了两个属性都允许为 nil 的情况,它们有可能导致强引用循环。这种情况最好用弱参考来解决。两个实体都可以存在而不严格依赖另一个实体。
Person
Apartment
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 } }
在这个例子中,aCustomer可能有也可能没有CreditCard,但是 aCreditCard 总是 与 a 相关联Customer。为了表示这一点,Customer该类具有一个可选card属性,但CreditCard该类具有一个非可选(和无主)customer属性。
Customer
CreditCard
card
customer
Customer ===(strong)==> CreditCard Customer <==(unowned)== CreditCard
Customerand示例显示了一种情况,其中一个允许为 nil的CreditCard属性和另一个不能为 nil 的属性有可能导致强引用循环。这种情况最好使用无主引用来解决。
苹果的注意事项:
弱引用必须声明为变量,以表明它们的值可以在运行时改变。弱引用不能声明为常量。
还有第三种情况,两个属性都应该始终有一个值,并且一旦初始化完成,两个属性都不应该为 nil。
在使用闭包时,还有一些经典的保留循环场景要避免。
为此,我鼓励您访问Apple 文档或阅读本书。