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 崩溃?

UIView 未自动释放。我的问题在哪里?

iphone:多次自动释放对象