Reputation: 961
I noticed that something that seems strange to me is happening with my code shown bellow, and I would like to understand what's exactly happening and why. I'm using ARC.
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSMutableDictionary *d1=[[NSMutableDictionary alloc]init];
NSLog(@"before loop");
for (int i=0; i<1000; i++) {
NSLog(@"looping");
}
NSLog(@"before autoreasepool block end");
}
NSLog(@"after autoreasepool block end");
return 0;
}
As an output I get that:
...
2014-07-11 21:48:20.637 testARC[24786:303] looping
2014-07-11 21:48:20.638 testARC[24786:303] looping
2014-07-11 21:48:20.638 testARC[24786:303] before autoreasepool block end
2014-07-11 21:48:20.638 testARC[24786:303] freed
2014-07-11 21:48:20.639 testARC[24786:303] after autoreasepool block end
where freed is written when d1 dealloc method is called.
My question is: it seems to me that d1 is being autoreleased, when I think it shouldn't. If I was writing the release and retain calls myself I would have released d1 before the loop, not at the end of the autorelease block, and I'm assuming ARC should do the same shouldn't it?
Thanks in advance.
Upvotes: 0
Views: 164
Reputation: 299345
There is no autorelease here; there just isn't a release until the end of the scope. You can demonstrate this by putting braces around the d1
assignment. You'll see that it will be deallocated when it goes out of scope, not when the autorelease pool drains.
ARC is never obligated to shorten the lifetime of objects. The optimizer is just permitted to do so in certain cases. This should be one of those cases where it's allowed to (since this is a local variable of automatic storage duration, so you may want to open an enhancement request to the compiler team, but it's not a bug.
By scoping, I just mean this:
int main(int argc, const char * argv[])
{
@autoreleasepool {
{ // These limit the scope of d1
NSMutableDictionary *d1=[[NSMutableDictionary alloc]init];
} // These limit the scope of d1
...
}
NSLog(@"after autoreasepool block end");
return 0;
}
But you should break those out into their own functions in most cases.
Upvotes: 2