iPhone:关于 NSAutoreleasePool 的困惑

Posted

技术标签:

【中文标题】iPhone:关于 NSAutoreleasePool 的困惑【英文标题】:iPhone: Confusion about NSAutoreleasePool 【发布时间】:2011-11-17 09:53:14 【问题描述】:

我阅读了 NSAutoReleasePool 并了解它使 iPhone 上的内存管理更容易。它在 NSObject 上可用,因此自动释放消息可用于每个对象实例。此外,我不应该经常使用自动释放,因为 NSAutoReleasePool 使用缓存内存,如果有很多自动释放的对象,您可能会耗尽内存。我的理解正确吗?

我不明白的一件事是像在以下方法中那样显式创建 NSAutoreleasePool 的目的是什么?它来这里的目的是什么?是不是像自动释放 imgData、img 对象一样?因为我可以看到这些对象并没有在这个方法中释放。

- (void)loadImage 
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *img = [UIImage imageNamed: @"default_user.png"];
if(![[imgURL absoluteString] isEqualToString: @"0"]) 
    NSData *imgData = [NSData dataWithContentsOfURL: imgURL];
    img = [UIImage imageWithData: imgData];

if([target respondsToSelector: action])
    [target performSelectorOnMainThread: action withObject: img waitUntilDone: YES];
[pool release];

谢谢。

【问题讨论】:

【参考方案1】:

您可以使用本地自动释放池来帮助减少峰值内存 脚印。当您的池被耗尽时,临时对象是 释放,这通常会导致它们被释放 减少程序的内存占用。

我可以建议创建这个显式自动释放池来管理图像加载。可能该图像具有较大的大小(以 Mb 为单位),并且该池可以保证内存将尽快释放。所有自动释放池都组织在堆栈中,因此这个内部池将比主池提前耗尽。

【讨论】:

【参考方案2】:

自动释放背后的想法是保持应用程序的低内存使用。你看看你是否没有使用过这个自动释放,那么这个数据就会进入应用程序的主自动释放所以即使你不再需要这个图像,它仍然会留在内存中并增加它的占用空间。创建一个新的自动释放会立即释放内存。(图像的大小可能很大。)

【讨论】:

哈哈哈,Steve Jobs 帮助AppleDeveloper ... 有趣。 自动释放对象不会“仅在应用程序终止时被释放”。当没有对象声称拥有所有权并且它没有被使用时,它将被释放。我曾经有一个错误,当我从集合中删除它时,自动释放会释放我的对象。虽然它不是完全可预测的,它似乎在线程不在您的代码中时释放,但在我的错误中,它是在将其返回到另一个方法时释放的。 是的,您是对的,一旦您退出特定循环,某些对象将被释放。铍已经非常清楚地解释了我想说的。(很抱歉造成混乱。)【参考方案3】:

规则是您必须在每个将使用自动释放的线程中创建一个自动释放池。在您的示例中,img 变量是自动释放的,并且假设 loadImage 方法是线程的,您必须在使用任何自动释放的内存之前声明一个新池。

【讨论】:

autorelease 不仅用于线程......还有其他用途,如上所述。

以上是关于iPhone:关于 NSAutoreleasePool 的困惑的主要内容,如果未能解决你的问题,请参考以下文章

iOS关于iPhone6和iPhone6 Plus的屏幕适配问题

需要关于在没有 iphone 但我有 ipod touch 的情况下提交 Iphone 应用程序的帮助

关于 iPhone 上的 ProtocolBuffers

有没有文件可以告诉我关于 iphone 的最佳信息? [关闭]

关于使用多态显示 iPhone/iPad ViewControllers

关于 iPhone 中的内存管理