CodeSmile
CodeSmile

Reputation: 64477

What might be a strategy to detect a retain cycle in an object hierarchy programmatically?

I'm writing an ARC-enabled framework which creates a hierarchy of objects, not unlike Cocoa's view hierarchy. Each controller object can have several subcontrollers. Controllers may have references to each other, which poses the potential risk of creating a retain cycle.

I know how to avoid retain cycles. I want to know if there's a way for me to detect programmatically that a retain cycle exists and prevents an object from deallocating?

At some point, the existing root controller will be replaced by a new root controller. Since I'm using ARC I can't use retainCount to check the existing controller's retain count. Which is not to be trusted anyway from what I've read.

I have a test setup where the root controller has two sub controllers, and each of them has a strong reference to the other. In that case the root controller does not run dealloc, neither do the other two controllers when the root controller is replaced with a new controller. As expected. I was thinking that given this scenario, there should be some way for me to determine whether that root controller did actually deallocate or not.

Possible Solution: I did assign the to-be-replaced root controller to a zeroing weak property on a global object shortly before replacing the controller. Then I have setup a timer so that after a fraction of a second I check if the property is nil or not. If it's nil, the controller did deallocate. If it's not nil, it probably indicates a memory leak likely to have been caused by a retain cycle somewhere in the hierarchy. In that case I print a log statement for as long as the replaced controller is not nil to get the developer's attention.

This works, but are there any alternative (better) solutions? Or possible caveats with this solution?

Specifically, how much time can pass before the object deallocates - is this guaranteed to be instantaneous or can deallocation be delayed and if so, for how long?

Upvotes: 4

Views: 277

Answers (1)

justin
justin

Reputation: 104698

I'm writing an ARC-enabled framework which creates a hierarchy of objects, not unlike Cocoa's view hierarchy…

Stop right there. Just introduce that relationship into your hierarchy. Views have parents, subviews, etc. -- consider how they interact and keep each other alive for appropriate lengths. Teach your objects about the relations they need, and teach them how to clean up after themselves. Simplified:

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

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

then if you also need to exchange nodes (e.g. your root), teach them to exchange nodes.

Upvotes: 0

Related Questions