ARC:Swift中的强引用和弱引用
我对撰写有关参考文献的博客的兴趣始于IBOutlets。 我一直想知道为什么IBOutlet很弱,或者这意味着什么。 弱? 我问自己,什么是弱变量?
考虑到这个问题,我继续阅读Apple的文档以了解其含义。 我几乎不知道,虚弱是一个比我想象的要复杂的话题的一部分。
我发现苹果使用自动引用计数(ARC)来管理和跟踪应用程序上的内存使用情况。 使用强,弱或无主等引用是使ARC知道何时为任何给定对象释放内存的方法。 在这篇文章中,我将重点放在强引用和弱引用上,因为无所有权将被保存以供以后的帖子使用。
让我们从强大开始
我们中的许多人甚至在没有意识到的情况下在代码中使用强引用。 实际上,每次我们声明一个类属性时,除非我们另外指定,否则它默认为强引用。
var name = String()
这是强参考周期的外观的直观表示:
本质上,强引用用于描述对象之间的关系。 当一个对象强烈引用另一个对象时,这将创建一个保留周期,以防止释放被引用的对象并将保留计数增加到1。换句话说,这些对象现在彼此保持活动状态。
在下面,我创建了两个类,一个类为Person类型,一个类型为Pet类型,它们具有强大的引用周期,以便我们可以大致了解代码中的内容。
类人{
变量名称:字符串
var pet:宠物?
初始化(名称:字符串,宠物:宠物?){
self.name =名称
self.pet =宠物
}
}
宠物类{
var所有者:个人?
var pet:字串
init(所有者:人,宠物:字符串){
self.owner =所有者
self.pet =宠物
}
}
在此示例中, Person通过其pet属性强烈引用了Pet , Pet通过其所有者所有权强烈引用了Person 。 此示例的问题在于,由于这些对象之间具有强引用,因此当不需要其中一个对象时,ARC无法释放内存。
从理论上讲,如果Pet在任何时候都不为零,那么Person仍然会强烈引用Pet,并且即使该类为nil,也无法释放该类的内存。 反过来,如果Person在任何时候都不为零,ARC也将无法为此对象释放任何内存。
为了防止此保留周期,我们可以创建保存弱引用的属性。
参考文献薄弱
弱引用是在声明之前使用关键字weak创建的。
弱变量名称:字符串?
与强引用不同,弱引用的保留计数为零,这是因为被引用的对象在某个点上可能保留缺失值,并且有可能被ARC释放。 对象之间的关系如下所示:
按照上面的示例,我们可以在一个类中更改属性,以使其对另一个类的引用微弱,如下所示:
类人{
变量名称:字符串
弱瓦尔宠物:宠物?
初始化(名称:字符串,宠物:宠物?){
self.name =名称
self.pet =宠物
}
}
宠物类{
var所有者:个人?
var pet:字串
init(所有者:Person ?,宠物:String?){
self.owner =所有者
self.pet =宠物
}
}
关于我们的代码, Pet类对Person类有很强的引用,而Person类对Pet类却有很弱的引用。
当我们拥有一个对对象的弱引用的属性时,它的类型将是可选的,因为它具有在运行时变为nil的能力。 这意味着,如果Pet在任何时候变为nil, Person类将在其pet属性中释放为此类型存储的内存。
考虑到这一点,弱引用永远不会是一个常数,因为它需要能够变异。
我们什么时候应该使用强引用和弱引用?
在创建诸如类之类的引用类型时,应考虑强引用和弱引用。 结构和枚举是值类型,因此使用任何ARC关键字都不适用于这些情况。
当父对象引用子对象时,应使用强引用,而不是相反。 也就是说,子类不应强烈引用父类。
应该使用弱引用来避免保留周期,并且对象可能会在其生命周期的任何时候变为零。