Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C associated objects leaking under ARC

I have encountered with a strange objc_setAssociatedObject behavior under ARC. Consider the following code:

static char ASSOC_KEY;

@interface DeallocTester : NSObject
@end

@implementation DeallocTester
- (void) dealloc
{
    NSLog(@"DeallocTester deallocated");
    //objc_setAssociatedObject(self, &ASSOC_KEY, nil, OBJC_ASSOCIATION_RETAIN);
}
@end

@implementation AppDelegate
- (void) applicationDidFinishLaunching:(UIApplication *)application
{
    NSObject *test = [[DeallocTester alloc] init];
    objc_setAssociatedObject(test, &ASSOC_KEY, [[DeallocTester alloc] init],
                             OBJC_ASSOCIATION_RETAIN);
}

I'm creating an instance of DeallocTester, then I set another DeallocTester as an associated object for it, then both of them go out of scope.

I expect the -dealloc of the first object to be called, then the associated object to be deallocated too, but I see the "DeallocTester deallocated" message printed only once. If I uncomment the objc_setAssociatedObject line in -dealloc, the second object gets deallocated too.

The Objective-C reference states that associated objects are deallocated automatically upon object destruction. Is it a compiler/ARC/whatever issue or am I missing something?

Update

This sample code is actually working if you run it from a brand-new project. But I have two ARC-enabled projects where it doesn't. I'll do some investigation and provide a better sample.

Update 2

I've filled a rdar://10636309, Associated objects leaking if NSZombie objects enabled in ARC-enabled project

like image 722
iHunter Avatar asked Jan 03 '12 09:01

iHunter


1 Answers

I've found a source of a problem - I had NSZombie objects enabled in both my projects where this bug appears.

As far as I understand, when zombie objects are enabled, the normal instances are replaced with NSZombie upon deallocation, but all the associated objects are left alive! Beware of that behavior!

I've created a rdar://10636309

Update: There's a workaround by Cédric Luthi, and this issue appears to be fixed in iOS 6.

like image 71
iHunter Avatar answered Nov 17 '22 14:11

iHunter