Search code examples
iosobjective-cautomatic-ref-countingdealloc

Hooking end of ARC dealloc


Given the following simple implementation:

@implementation RTUDeallocLogger
-(void)dealloc
{
    NSLog(@"deallocated");
}
@end

we run the following code under ARC:

@implementation RTURunner
{
    NSArray* arr;
}
-(void)run{
    arr = [NSArray
           arrayWithObjects:[[RTUDeallocLogger alloc]init],
                            [[RTUDeallocLogger alloc]init],
                            [[RTUDeallocLogger alloc]init],
                            nil];
    NSLog(@"nulling arr");
    arr = NULL;
    NSLog(@"finished nulling");
}
@end

we get the following log output:

nulling arr
finished nulling
deallocated
deallocated
deallocated

I'd like to perform an action after all the deallocations have finished. Is this possible?

The aim of this question is really to understand a little more about the mechanics of ARC, in particular, at what point ARC triggers these deallocations, and whether or not this can ever happen synchronously when I drop references.


Solution

  • -dealloc is always synchronous, and occurs when the last strong reference is removed. In the case of your code though, +arrayWithObjects: is likely (if compiled at -O0 at least) putting the array in the autorelease pool, so the last strong reference is removed when the pool drains, not when you set the variable to NULL (you should use nil for ObjC objects, btw).

    You can likely avoid having the object in the autorelease pool by using alloc/init to create, and you may (implementation detail, bla bla) be able to avoid it by compiling with optimizations turned on. You can also use @autoreleasepool { } to introduce an inner pool and bound the lifetime that way.