【发布时间】:2015-08-12 15:50:45
【问题描述】:
我在 Objective C 中有一个带有保留周期的数据结构,我正试图找出一种合理的方法来打破它们。由于我对数据结构的要求,这里的常用规则似乎都没有帮助(例如“对父关系使用弱”)。
数据结构本质上是一棵树。但是,我想确保,如果保留树中的 any 节点,则保留整个树。例如,在这个非常简单的树中:
A
/ \
B C
如果有人保留了 A、B 或 C,那么应该保留整个树并且可以从任何节点向上/向下移动。只有在没有人保留任何个节点时,才应释放树中的节点。
我想出的仅有的两个解决方案不是很漂亮。有谁知道更优雅的解决方案?
作为参考,以下是我想到的两个解决方案(两者都与retainCount混淆,这很恶心):
创建一个 TreeHelper 对象,该对象强烈地保存在树中的所有节点上。所有节点都使用弱指针来引用所有其他节点。树中的所有节点在其 retainCount > 1 时强烈保留 TreeHelper,而在 retainCount == 1 时弱保留。这应该有效,但需要我们使用非 ARC 代码,以便我们可以覆盖保留/释放并更改 TreeHelper 的所有权。
创建一个 TreeHelper 对象,该对象强烈地持有树中的所有对象。所有节点都使用弱指针来引用所有其他节点并强持有 TreeHelper。它会定期执行垃圾回收并检查所有对象的retainCount。如果它们都是 == 1,那么它会清除所有对象以释放它们。这也应该可以,但是垃圾收集并不漂亮,并且存在一些严重的线程安全问题。
【问题讨论】:
-
不要使用
retainCount,为类添加计数。系统retainCount由系统根据系统需要进行管理/更改。此外,通过不使用retainCount,您可以使用 ARC。 -
@zaph 说了什么。我不得不调试在某些
retainCount值上切换行为的代码。这是精神错乱的诱导;一个流浪者retain/autorelease,突然之间,您的缓存语义更改代码在池排水的中间启动,而不是在有序的对象图破坏中间。
标签: objective-c tree automatic-ref-counting