可能是以编程方式检测对象层次结构中的保留周期的策略?

时间:2012-09-26 21:23:48

标签: objective-c memory-leaks automatic-ref-counting retaincount retain-cycle

我正在编写一个支持ARC的框架,它创建了一个对象层次结构,与Cocoa的视图层次结构不同。每个控制器对象可以有几个子控制器。控制器可能相互引用,这可能会产生保留周期。

我知道如何避免保留周期。我想知道我是否有办法以编程方式检测保留周期是否存在并阻止对象解除分配?

在某些时候,现有的根控制器将被新的根控制器替换。由于我使用ARC,因此我无法使用retainCount来检查现有控制器的保留计数。不管怎么说,我都不会信任。

我有一个测试设置,根控制器有两个子控制器,每个子控制器都有一个强引用。在这种情况下,根控制器不会运行dealloc,当根控制器被新控制器替换时,其他两个控制器也不运行。正如所料。我在想,鉴于这种情况,我应该有一些方法来确定根控制器是否确实解除了分配。

可能的解决方案:在更换控制器之前不久,我确实将要替换的根控制器分配给全局对象上的归零弱属性。然后我设置了一个计时器,以便在几分之一秒后检查属性是否为零。如果它是零,则控制器确实取消分配。如果它不是nil,则可能表示内存泄漏可能是由层次结构中某处的保留周期引起的。在这种情况下,只要被替换的控制器不是零,我就会打印一个日志语句,以引起开发人员的注意。

这有效,但有没有其他(更好)的解决方案?或者这个解决方案可能需要注意?

具体而言,在对象解除分配之前可以经过多长时间 - 这是保证是即时的还是可以延迟解除分配,如果是,可以延迟多长时间?

1 个答案:

答案 0 :(得分:0)

  

我正在编写一个支持ARC的框架,它创建了一个对象层次结构,与Cocoa的视图层次结构不同......

停在那儿。只需将这种关系引入您的层次结构。观点有父母,子视图等。 - 考虑他们如何互动并保持彼此活着适当的长度。教你的对象他们需要的关系,并教他们如何清理自己。简化为:

- (void)tearDownState
{
  if (self.isTearingDown)
    return;

  [self setTearingDown];
  for (Node * at in self.subnodes) {
    [at tearDownState];
  }
  self.subnodes = 0;
  ...

然后,如果您还需要交换节点(例如您的根),请教他们交换节点。