自动释放池是什么?

73

可能重复:
为什么要使用自动释放池?

所有的Objective-C起始页面在主函数声明下方都会有一个默认的@autoreleasepool{...}语句。但这个语句实际上是做什么的呢?新的Objective-C版本会自动释放对象,而删除这行代码对程序没有影响。这个命令真的必要吗?


或者是为什么Xcode 4.2在main.m中使用autoreleasepool而不是NSAutoreleasePool? - Richard J. Ross III
高级内存管理编程指南标题信息:<高级内存管理编程指南> 链接:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI - black_pearl
1个回答

97
@autoreleasepool语句所做的工作与使用NSAutoreleasePool类时相同。NSAutoreleasePool的工作方式有些奇怪,因为创建它会在整个应用程序中产生影响;@autoreleasepool创建一个作用域范围,并清晰地表明了池内的内容和何时排放(当它超出范围时)。根据苹果公司的说法,它还更加高效。
autorelease池的概念很简单,每当一个对象实例被标记为自动释放(例如:NSString* str = [[[NSString alloc] initWithString:@"hello"] autorelease];),它将在那个时间点上具有+1的保留计数,但在运行循环结束时,池被排空,任何标记为自动释放的对象都将其保留计数减少。这是一种在您为自己准备什么将保留它的东西之前使对象保持活动状态的方法。
在ARC中,虽然开发人员不使用autorelease方法,但管理ARC的底层系统会为您插入它。请记住:ARC所做的一切只是在适当的时间为您插入retainreleaseautorelease调用。因此,现有的AutoreleasePool概念需要继续存在。
如果删除autorelease池,则您的对象将开始泄漏。
在基于引用计数的环境中,Cocoa希望始终有一个自动释放池可用。如果没有池可用,则自动释放的对象不会被释放,从而导致内存泄漏。在这种情况下,您的程序通常会记录适当的警告消息。

这是否意味着,如果我使用ARC并从“@autoreleasepool {}”之外的某个地方释放对象,该对象仍然存在直到@autoreleasepool块的结束? - Michael
3
如果你手动释放一个自动释放的对象,在自动释放池结束时,已经被dealloc的对象将不再存在,并且你可能会在框架或机器代码中的某个位置遇到异常。如果这是一条长代码路径,你的应用程序可能会在看似无关的地方崩溃,导致混淆。 - jcpennypincher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接