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属性强烈引用了PetPet通过其所有者所有权强烈引用了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关键字都不适用于这些情况。

当父对象引用子对象时,应使用引用,而不是相反。 也就是说,子类不应强烈引用父类。

应该使用引用来避免保留周期,并且对象可能会在其生命周期的任何时候变为零。