我注意到,对我来说似乎很奇怪的事情发生在下面显示的代码中,我想了解究竟发生了什么以及为什么。我正在使用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;
}
作为输出,我得到了:
...
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
当调用d1 dealloc方法时写入freed。
我的问题是:在我看来d1正在被自动释放,而我认为它不应该。 如果我自己编写发布并保留调用,我会在循环之前释放d1,而不是在自动释放块结束时,我假设ARC应该这样做,不应该吗?
提前致谢。
答案 0 :(得分:2)
这里没有自动释放;在范围结束之前,我们不会发布任何内容。您可以通过在d1
作业周围添加大括号来证明这一点。您将看到它在超出范围时将被释放,而不是在自动释放池耗尽时释放。
ARC从未有义务缩短对象的生命周期。在某些情况下,优化器只允许这样做。这应该是允许的情况之一(因为这是local variable of automatic storage duration,因此您可能想要向编译器团队打开增强请求,但这不是错误。
通过范围界定,我的意思是:
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;
}
但是在大多数情况下你应该把它们分解成自己的功能。