繁体   English   中英

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

[英]Should an autorelease call crash if there is no nsautoreleasepool declared?

对不起,我是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的情况下编写应用程序,我只是想弄清楚它是如何工作的。 这个事实让人怀疑我以为我知道什么。

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

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

来自NSAutoreleasePool文档 ......

在引用计数环境中,Cocoa期望有一个始终可用的自动释放池。 如果池不可用,则自动释放的对象不会被释放并且您会泄漏内存。 在这种情况下,您的程序通常会记录适当的警告消息。

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

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

直接来自苹果文档

NSApplication类在初始化期间和事件循环内部(特别是在其初始化(或sharedApplication)和run方法中)设置自动释放池(NSAutoreleasePool类的实例)。 类似地,Application Kit添加到NSBundle的方法在加载nib文件期间使用自动释放池。 在相应的NSApplication和NSBundle方法的范围之外,无法访问这些自动释放池。 通常,应用程序在事件循环运行时或通过从nib文件加载对象来创建对象,因此这种缺乏访问通常不是问题。 但是,如果您确实需要在main()函数本身中使用Cocoa类(除了加载nib文件或实例化NSApplication),您应该在使用类之前创建自动释放池,然后在完成后释放池。 有关更多信息,请参阅Foundation Framework Reference中的NSAutoreleasePool

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM