1

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

在某些情况下,我看到该过程使用了多达 2GB 的内存。在一个非常相似的问题上对 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,可以执行以下操作(如本主题中所建议):

+(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 为我做这件事会很好。

4

1 回答 1

3

使用@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;
}
于 2012-08-21T13:39:13.847 回答