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.
-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.