在Objective C(ARC)中避免在树状数据结构中保留周期

时间:2015-08-12 15:50:45

标签: objective-c tree automatic-ref-counting

我在Objective C中有一个带有保留周期的数据结构,我正试图找出一种合理的方法来打破它们。由于我对数据结构的要求,通常的规则似乎都没有帮助(例如“使用弱父关系”)。

数据结构本质上是一棵树。但是,我想确保,如果保留树中任何节点,则保留整个树。例如,在这个非常简单的树中:

  A
 / \
B   C

如果有人保留A,B或C,则应保留整个树,并且可以从任何节点上/下走。只有当没有人保留任何节点时,才应释放树中的节点。

我提出的唯一两个解决方案并不是很漂亮。有谁知道更优雅的解决方案?

作为参考,以下是我想到的两个解决方案(两者都与retainCount混淆,这是粗略的):

  1. 创建一个TreeHelper对象,该对象强烈保存在树中的所有节点上。所有节点都使用弱指针来引用所有其他节点。树的所有节点在其retainCount> gt时强烈地保持在TreeHelper上。 1,当retainCount == 1时弱。这应该有效,但要求我们使用非ARC代码,以便我们可以覆盖保留/释放并更改TreeHelper的所有权。

  2. 创建一个TreeHelper对象,该对象强烈保存树中的所有对象。所有节点都使用弱指针来引用所有其他节点并强烈保持TreeHelper。它会定期执行垃圾收集并检查所有对象的retainCount。如果它们都是== 1,则它会释放所有对象以释放它们。这也应该有效,但垃圾收集并不漂亮,并且存在一些严重的线程安全问题。

1 个答案:

答案 0 :(得分:1)

没有什么可以阻止你使用ARC作为“treehelper”方案。

首先,让你的树不透明。对节点的任何访问(对父节点都有弱引用以避免保留周期)都会通过treehelper的方法(可能将其称为TreeWrapper或TreeRef)。

每当第三方访问某个节点时,您都​​会返回一个新的数据结构NodeWrapper,该结构对您想要的特定节点和根节点都有强引用。第三方建立了对该对象的强引用,而不是节点本身。

结果是当最后一个对象被释放时,整个树被释放,只要有一个NodeWrapper存在,你的树就会生存,满足你的要求。

Never use retainCount for anything, even if you aren't using ARC.