OS X 应用程序的自动释放池在哪里创建和耗尽?
Posted
技术标签:
【中文标题】OS X 应用程序的自动释放池在哪里创建和耗尽?【英文标题】:Where is the autorelease pool for OS X application created and drained? 【发布时间】:2011-11-17 08:58:50 【问题描述】:我正在为 ARC 重构我的 OS X 应用程序。打开 main.m 文件,我确信我会找到 Autorelease Pool 实例化和耗尽(如 ios 项目),但令我惊讶的是它不存在。
所以我的第一个问题是:
主自动释放池在哪里?我的下一个问题是:
如果没有创建主自动释放池,我需要创建它吗?还是以某种自动方式释放了自动释放的对象?【问题讨论】:
【参考方案1】:您的 main.m 文件应该有以下调用:
NSApplicationMain(argc, (const char **)argv);
NSApplicationMain()
负责创建应用程序,即NSApplication
的实例,而后者又负责创建自动释放池:
NSApplication 类在初始化期间和事件循环内设置自动释放池(NSAutoreleasePool 类的实例) - 特别是在其初始化(或 sharedApplication)和运行方法内。
这意味着,在一般情况下,您不必担心创建自动释放池,因为 NSApplication
已经在初始化和事件循环中这样做了。在某些情况下,可能需要/希望创建自己的自动释放池,例如一种具有创建许多自动释放对象的循环的方法。在这种情况下,每次循环迭代都有一个自动释放池是个好主意。
【讨论】:
我有 NSString *a = [NSString string];主函数中的行,我得到 *** __NSAutoreleaseNoPool(): Object 0x7fff703fd190 of class NSCFString autoreleased with no pool in place - 只是泄漏为什么? @Parag 如果您在main()
中执行此操作,那么您不会调用(或尚未调用)NSApplicationMain()
,这反过来不会创建NSApplication
,它会自动创建自动释放池。如果您不使用NSApplication
,则需要创建自己的自动释放池。
返回 NSApplicationMain(argc, (const char **) argv);声明也在我的 main() function.int main(int argc, char *argv[]) NSString *a = [NSString string];返回 NSApplicationMain(argc, (const char **) argv);
@Parag 这就是我写(或尚未调用)的原因。如果您要创建一个字符串 before NSApplicationMain()
被调用,则没有自动释放池,您应该创建自己的。【参考方案2】:
通常情况下,Apple 的文档中很好地涵盖了这个主题。例如,查看this Cocoa Fundamentals Guide chapter 的主函数部分中发生的情况。引用与此问题相关的部分(已由 Bavarious 解释):
几乎所有 Cocoa 应用程序中的 main 函数都非常 简单的。在 Mac OS X 中,它只包含一个函数调用。
#import <AppKit/AppKit.h>
int main(int argc, const char *argv[])
return NSApplicationMain(argc, argv);
NSApplicationMain 函数 创建应用程序 对象,设置自动释放池,加载初始用户界面 从主 nib 文件,并运行应用程序,从而请求 它开始处理在主事件循环上收到的事件。
【讨论】:
以上是关于OS X 应用程序的自动释放池在哪里创建和耗尽?的主要内容,如果未能解决你的问题,请参考以下文章
为啥有时会立即释放内存,而有时仅在自动释放池耗尽时才释放内存?
当自动释放池耗尽时,NSFileAttributes dealloc 中的 SIGSEGV SEGV_ACCERR 崩溃?