通知每个持有B对象引用的A对象已删除B对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通知每个持有B对象引用的A对象已删除B对象相关的知识,希望对你有一定的参考价值。

我一定很难理解这个标题的意思,但我会试着解释一下。

我们有一个类Person,它拥有各种领域:namesurnameage等。这些是任何给定的Person的独特特征。但是,让我们考虑一下,每个Person都有一个引用类House的另一个对象的字段。有些人拥有它,这意味着一些House对象引用,其他人没有,这意味着一个Null对象引用(抱歉)。另一件事是我们假设有些人住在同一个房子里,这意味着从不同的House对象多次引用相同的Person。到现在为止还挺好。

现在,我们处于这样一种情况:一个火热的Asteroid物体飞过天空,并破坏了一个美丽的多层House物体,其中有许多Person物体居住。 Asteroid使用Town对象对此建筑物的引用并将其设置为Null。然而,可怜的Person物体仍然认为他们有HouseHouse的参考仅在Town的水平上被改变,所以它仍然在记忆中并且每个居民都有它的参考。这意味着垃圾收集器无法摆脱House对象和Person对象仍然可以使用伪现有House

我认为现在的问题很清楚。我们该如何处理这种情况?

我想过使用一些boolean旗帜:true如果存在,false如果没有,当一个Person来到曾经是他们的House的火山口时,他们设置他们对Null的引用,因为没有这样的对象了。它提供了一个解决方案,但垃圾收集器将无法摆脱该对象,因为不是每个居民都确保House不存在。

另一种解决方案可能是House对象具有对驻留在其中的所有Person对象的引用数组。在House被摧毁之后,我们设置了对Null的所有引用,遍历数组。现在垃圾收集器很容易摆脱对象,但这可能代价高昂:如果它是摩天大楼怎么办?

还有其他可能吗?

答案

如你所说,你可以在House上使用旗帜。要解决垃圾收集器的问题,只需通过WeakReference连接House和Person。当对象只有弱引用引用时,它有资格进行垃圾回收。

另一答案

另一个解决方案可能是House对象具有对驻留在其中的所有Person对象的引用数组。众议院被摧毁后,我们将所有引用设置为Null,遍历数组。现在垃圾收集器很容易摆脱对象,但这可能代价高昂:如果它是摩天大楼怎么办?

它可能成本很高,但不会大大增加总体成本。

关于记忆,如果你的摩天大楼有一个长度为N的列表,那么有N个人参考它。这意味着您只将参考总数增加了一倍。

关于时间,它大致相同:你需要清理N个引用,但这些引用必须先设置。所以,你只是把工作加倍。

加倍听起来很糟糕,但你加倍可能的小值。

请注意,WeakReference也不是免费的。用弱引用替换对House的正常引用意味着再多一个对象,这比(强)引用更昂贵。

如果你真的想节省内存,那么将List<Person>存储在House肯定是更好的方法。

它还具有这样的列表的优点,这可能有用一天。冗余很糟糕,因为您始终必须保持前向和后向引用同步。

以上是关于通知每个持有B对象引用的A对象已删除B对象的主要内容,如果未能解决你的问题,请参考以下文章

【OC梳理】循环引用及解决

iOC中block下的__block、__Strong、__weak

JVM 垃圾回收算法

java垃圾回收

Android中使用Handler造成内存泄露的分析和解决

Android中使用Handler造成内存泄露的分析和解决