如果没有声明nsautoreleasepool,是否应该自动释放调用崩溃?

时间:2012-01-09 19:22:02

标签: iphone cocoa-touch autorelease nsautoreleasepool

对不起,我是cocoa编程的新手,我不确定我是否真的了解nsautoreleasepool是如何工作的。

我读过的每个地方都说有关NSAutoreleasePool的内容对所有自动释放调用负责(谈论最后宣布的NSAutoreleasePool)。

考虑以下代码:

int main(int argc, char *argv[]) {

    //NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    //[pool release];
    return retVal;
}

在我申请的某些时候,我也会接近这个:

NSString* b = [[NSString alloc] initWithFormat:@"%d", 10];
[b autorelease];

考虑到我没有NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];任何地方...... [b autorelease];是否应该使应用程序崩溃?但是应用程序看起来似乎很好。

观察:我没有打算在没有NSAutoreleasePool的情况下编写应用程序,我只是想弄清楚它是如何工作的。这个事实让我怀疑我认为我知道什么。

4 个答案:

答案 0 :(得分:3)

您只需在控制台中收到一条警告,指出没有自动释放池并且该对象已泄露。

如果您真的想了解自动释放池,请阅读Mike Ash's Let's build NSAutoreleasePool

答案 1 :(得分:1)

来自documentation for NSAutoreleasePool ...

  

在参考计数环境中,Cocoa期望有一个   自动释放池始终可用。如果没有游泳池,   自动释放的对象不会被释放而你会泄漏内存。在这   情况,您的程序通常会记录适当的警告信息。

这是非常自我解释的。您是否在控制台中收到与此相关的任何消息?

答案 2 :(得分:0)

直接来自apple documentation

  

NSApplication类设置自动释放池(实例)   NSAutoreleasePool类)在初始化期间和事件内部   循环特定的,在其初始化(或sharedApplication)中   并运行方法。同样,Application Kit添加的方法也是如此   NSBundle在加载nib文件期间使用自动释放池。   这些自动释放池不在范围之外   相应的NSApplication和NSBundle方法。通常,一个   应用程序在事件循环运行时创建对象或   通过从nib文件加载对象,所以通常缺乏访问权限   不是问题。但是,如果您确实需要在其中使用Cocoa类   main()函数本身(除了加载nib文件或者   实例化NSApplication),您应该创建一个自动释放池   在使用类之前,然后在完成后释放池。   有关详细信息,请参阅NSAutoreleasePool in the Foundation Framework Reference

答案 3 :(得分:0)

UIApplicationMain()确保主线程运行事件循环,因此您的应用可以处理事件(例如,用户输入,计时器事件等),并且事件循环在开始迭代之前创建一个autoreleasepool并释放一次它完成了。从主线程的偶数循环调用的所有代码(例如所有UI代码)始终具有一个自动释放池,您无需执行任何操作。仅在使用与主线程不同的线程时才需要管理自动释放池(但仅在实际使用线程时才使用!当使用DispatchQueues或OperationQueues时,它们也将为您管理自动释放池),在极少数情况下,您想使用它们循环以保持较小的内存占用(自动释放池收集对象以供以后发布,但有时您不希望它收集太多对象从而变得太大,而是希望在自己循环的每次迭代中清除它,在这种情况下,您需要自己进行管理)。在大多数情况下,您不需要了解自动释放池,就可以编写一个完整的全功能应用程序,而无需每个人都听说过自动释放池。您只需要知道何时必须在自己拥有的对象上调用autorelease,并且这仅适用于非ARC代码,因为对于ARC,编译器会自动为您确定。