main.m 真的是每个事件创建主运行循环的自动释放池的地方吗?

Posted

技术标签:

【中文标题】main.m 真的是每个事件创建主运行循环的自动释放池的地方吗?【英文标题】:is the main.m really the place, where the autorelease pool of the main run loop is created by every event? 【发布时间】:2009-04-28 17:08:25 【问题描述】:
#import <UIKit/UIKit.h>

int main(int argc, char *argv[]) 
    NSLog(@"new event...");
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;

如果是这样,那么 main() 函数必须在每个事件上都被调用,对吗?但我试过了,“新事件......”日志消息只是在应用程序启动时出现。所以我猜主线程中肯定还有一个自动释放池。

【问题讨论】:

【参考方案1】:

没有。所有 Cocoa 或 CocoaTouch 类都需要存在自动释放池才能不泄漏内存。因此,现有的自动释放池需要调用 UIApplicationMain() 以覆盖在 UIApplicationMain() 上下文中实例化的任何(可能)自动释放对象。如您所见,在 UIApplicationMain 返回后,就在应用程序退出之前,该外部自动释放池已耗尽。内部(请记住,自动释放池可以嵌套,并且自动释放的对象被添加到最新/最深的池中)自动释放池在应用程序运行循环的每次迭代开始时创建,并在迭代结束时释放。因此,运行循环的每次迭代都会获得“自己的”自动释放池。如果处理一个事件可能会产生大量的自动释放内存(在 iPhone 上是个坏主意,但在 OS X 上很常见),您可能希望在事件处理代码中创建自己的内部自动释放池,该池可以在处理期间释放事件。

【讨论】:

最外面的“main()”自动释放池有什么意义,因为无论如何,操作系统在退出时都会回收所有应用程序内存?而且我很好奇为什么 Apple 没有在 UIApplicationMain() 的实现中简单地包含一个***自动释放池。 谢谢。是的,我也想知道......也许在 UIApplicationMain() 的主运行循环旁边发生了一些自动释放的东西...... 一个 +initialize 方法会在类收到第一条消息之前发送给它们。除非 UIApplicationMain(或任何用户提供的替代品)的编写者非常小心地实例化自动释放池,否则对 Cocoa 派生类的任何其他调用都可能导致内存泄漏——那些 +initialize 方法可能会自动释放对象。最安全的计划是在调用任何依赖 Cocoa 的代码之前建立一个自动释放池。当然,UIApplicationMain 无论如何都可以创建自己的自动释放池。 @Daniel 没有任何理由,除了明确和彻底地表明池需要在应用程序退出之前立即排空。 Barry,没有最外层的自动释放池不会导致正常意义上的泄漏,因为当 main() 无论如何返回时,所有内存都会被释放。但是,类可能会在 -dealloc 中执行除释放内存之外的其他操作,例如完成文件写入或干净地关闭网络连接。【参考方案2】:

不,这是您应用程序中最外层的函数,一个常规的 C 风格 main()。

iPhone 应用程序所做的一切都发生在 UIApplicationMain 中,包括所有事件处理。

【讨论】:

以上是关于main.m 真的是每个事件创建主运行循环的自动释放池的地方吗?的主要内容,如果未能解决你的问题,请参考以下文章

进入Qt事件循环后如何自动执行方法?

Qt ------ 主事件循环与 QEventLoop

在主事件循环之前如何创建一些对象?

线程机制与事件机制:进程与线程 浏览器内核 定时器引发的思考 JS是单线程执行的 浏览器的事件循环(轮询)模型

循环中的事件处理程序似乎使其下面编写的每个代码都无效

6wxWidgets 事件处理