我在Objective C中有一个带有保留周期的数据结构,我正试图找出一种合理的方法来打破它们。由于我对数据结构的要求,通常的规则似乎都没有帮助(例如“使用弱父关系”)。
数据结构本质上是一棵树。但是,我想确保,如果保留树中任何节点,则保留整个树。例如,在这个非常简单的树中:
A
/ \
B C
如果有人保留A,B或C,则应保留整个树,并且可以从任何节点上/下走。只有当没有人保留任何节点时,才应释放树中的节点。
我提出的唯一两个解决方案并不是很漂亮。有谁知道更优雅的解决方案?
作为参考,以下是我想到的两个解决方案(两者都与retainCount混淆,这是粗略的):
创建一个TreeHelper对象,该对象强烈保存在树中的所有节点上。所有节点都使用弱指针来引用所有其他节点。树的所有节点在其retainCount> gt时强烈地保持在TreeHelper上。 1,当retainCount == 1时弱。这应该有效,但要求我们使用非ARC代码,以便我们可以覆盖保留/释放并更改TreeHelper的所有权。
创建一个TreeHelper对象,该对象强烈保存树中的所有对象。所有节点都使用弱指针来引用所有其他节点并强烈保持TreeHelper。它会定期执行垃圾收集并检查所有对象的retainCount。如果它们都是== 1,则它会释放所有对象以释放它们。这也应该有效,但垃圾收集并不漂亮,并且存在一些严重的线程安全问题。
答案 0 :(得分:1)
没有什么可以阻止你使用ARC作为“treehelper”方案。
首先,让你的树不透明。对节点的任何访问(对父节点都有弱引用以避免保留周期)都会通过treehelper的方法(可能将其称为TreeWrapper或TreeRef)。
每当第三方访问某个节点时,您都会返回一个新的数据结构NodeWrapper
,该结构对您想要的特定节点和根节点都有强引用。第三方建立了对该对象的强引用,而不是节点本身。
结果是当最后一个对象被释放时,整个树被释放,只要有一个NodeWrapper
存在,你的树就会生存,满足你的要求。
Never use retainCount
for anything, even if you aren't using ARC.