Search code examples
objective-cmemory-managementmemory-leaksretaincount

Cross retain trouble


How do you get around the cross retain situation when two objects retain each other?

consider this class structure:

Container.h

@interface Container : NSObject {
    NSObject *child;
}

@property (nonatomic, retain) NSObject *child;
@end

Container.m

@implementation Container

@synthesize child;

- (void)dealloc {
    [child release];
    [super dealloc];
}

@end

Then when testing the memory retain count:

- (void)testDoubleRetain {
    Container *A = [[Container alloc] init];
    Container *B = [[Container alloc] init];

    NSLog(@"A retainCount: %d", [A retainCount]);//returns 1
    NSLog(@"B retainCount: %d", [B retainCount]);//returns 1
    [A setChild:B];
    [B setChild:A];

    NSLog(@"A retainCount: %d", [A retainCount]);//returns 2
    NSLog(@"B retainCount: %d", [B retainCount]);//returns 2

    [A release];
    [B release];

    NSLog(@"A retainCount: %d", [A retainCount]);//returns 1
    NSLog(@"B retainCount: %d", [B retainCount]);//returns 1
}

So, from my understanding the retain count supposed to be showing the right count. but how do I end up actually deallocating the objects, since after this block of code those two objects are gonna stay in memory.


Solution

  • Simple workaround may be to nil a child before releasing an object itself:

    A.child = nil;
    [A release];
    

    But to avoid your problem it may be worth rethinking your general program structure so you won't need to have 2 objects mutually retain each other (may be their relationship allow to use 'assign' property instead of 'retain' and you can make sure they won't get deallocated prematurely by other means - e.g. by putting all of them to some global container - that all will depend on your actual context)