【问题标题】:OS X ARC memory increase in repeated image loading重复加载图像时 OS X ARC 内存增加
【发布时间】:2012-08-16 20:50:53
【问题描述】:

在使用自动引用计数编写的应用程序中重复加载不同的 NSImage 时,我遇到了一个问题。似乎 ARC 没有正确释放图像对象,而是随着列表的迭代,内存使用量增加,直到迭代完成,此时内存被释放。

在某些情况下,我发现该过程使用了多达 2GB 的内存。 a good discussion on SO 有一个非常相似的问题,最终将进程放入 NSAutoReleasePool 并释放图像并排空池。如果我不使用 ARC,这也适用于我,但无法在 ARC 中调用这些对象/方法。

有什么方法可以在 ARC 中进行这项工作吗?似乎 ARC 应该自己解决这个问题 - 这让我认为这些对象没有被释放的事实一定是 OS X 的一个错误。(我正在用 XCode 4.2.1 运行 Lion)。

导致问题的代码如下所示:

+(BOOL)checkImage:(NSURL *)imageURL
{
    NSImage *img = [[NSImage alloc] initWithContentsOfURL:imageURL];
    if (!img)
         return NO;

    // Do some processing
    return YES;
}

此方法在循环中被重复调用(例如,300 次)。分析应用程序,内存使用量继续增加,为每个图像分配 7.5MB。如果不使用 ARC,则可以执行以下操作(如 this topic 中所建议的那样):

+(BOOL)checkImage:(NSURL *)imageURL
{
    NSAutoReleasePool *apool = [[NSAutoReleasePool alloc] init];
    NSImage *img = [[NSImage alloc] initWithContentsOfURL:imageURL];
    if (!img)
         return NO;

    // Do some processing

    [img release];
    [apool drain];

    return YES;
}

有谁知道如何强制 ARC 进行内存清理?目前,我已将该函数放在一个文件中,该文件使用 -fno-objc-arc 作为编译器标志传入。这工作正常,但如果让 ARC 为我做这件事会很好。

【问题讨论】:

    标签: objective-c macos automatic-ref-counting nsimage nsautoreleasepool


    【解决方案1】:

    使用@autoreleasepool,像这样:

    +(BOOL)checkImage:(NSURL *)imageURL
    {
        @autoreleasepool { // << push a new pool on the autotrelease pool stack
          NSImage *img = [[NSImage alloc] initWithContentsOfURL:imageURL];
          if (!img) {
             return NO;
          }
          // Do some processing
        } // << pushed pool popped at scope exit
        return YES;
    }
    

    【讨论】:

    • 这就是票。它甚至比使用非 ARC 方法更有效(相同文件的运行时 750MB 减少到大约 300MB)。
    • @djbp 正确 - 当/如果达到 return NO; 时,原始版本会搞砸自动释放池堆栈。
    • 很公平 - 这实际上不是我的代码所做的。 bool 值实际上是在 //Do some processing bit 中算出来并返回的。不过谢谢 - 很高兴知道未来。
    • @djbp 是的,静态分析器也会指出这一点。很高兴它成功了。
    • 出于好奇,您知道为什么需要将进程包装在自动释放池中吗?这可能是我对 ARC 工作原理的误解,但是如果 NSImage 对象是在该级别声明的,那么一旦方法退出,它肯定应该知道释放分配的内存吗?
    猜你喜欢
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    • 2012-12-24
    相关资源
    最近更新 更多