【问题标题】:Memory Leak while creating and copying Images with NSFiIlemanager on iPad App在 iPad App 上使用 NSFiIlemanager 创建和复制图像时出现内存泄漏
【发布时间】:2025-12-21 05:35:12
【问题描述】:

我在复制/创建图像宽度 NSFileManager 时出现内存泄漏,导致我的应用程序崩溃。

当我使用“分配”配置我的应用程序时,一切看起来都很好。分配的内存在每次递归期间从大约 1.5 MB 上升到 6 MB,然后再次下降到 1.5 MB。

但是“真实内存”和“虚拟内存”增长到大约 150MB,然后应用程序崩溃。

我之前收到过 1 级和 2 级内存警告。

这是我们使用的函数:

-(void) processCacheItems:(NSMutableArray*) originalFiles
{
    if ( [originalFiles count] == 0 )
    {
        [originalFiles release];
        return;
    }
    else
    {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

        NSString *curFileName = [originalFiles lastObject];
        NSString *filePath = [documentsDirectoryPath stringByAppendingPathComponent:curFileName];
        NSURL *fileURL = [NSURL fileURLWithPath:filePath];

        CGSize destinationSize = CGSizeMake(150,150);
        CGSize previewDestinationSize = CGSizeMake(1440.0, 1440.0);

        UIImage *originalImage = [UIImage imageWithContentsOfFile:filePath]; // AUTORELEASED

        // create thumb and copy to presentationfiles directory
        UIImage *thumb = [originalImage resizedImageWithContentMode:UIViewContentModeScaleAspectFit
                                                             bounds:destinationSize
                                               interpolationQuality:kCGInterpolationHigh]; // AUTORELEASED

        // the resizedImageWithContentMode: does not semm to make the problem, because when i skip this and just use the original file the same problem occours

        NSString *thumbPath = [thumbsDirectoryPath stringByAppendingPathComponent:curFileName];
        [fileManager createFileAtPath:thumbPath contents:UIImageJPEGRepresentation(thumb, 0.9) attributes:NULL];

        // create thumb and copy to presentationfiles directory
        UIImage *previewImage = [originalImage resizedImageWithContentMode:UIViewContentModeScaleAspectFit
                                                                    bounds:previewDestinationSize
                                                      interpolationQuality:kCGInterpolationHigh]; // AUTORELEASED

        NSString *previewImagePath = [previewsDirectoryPath stringByAppendingPathComponent:curFileName];
        [fileManager createFileAtPath:previewImagePath contents:UIImageJPEGRepresentation(previewImage, 0.9) attributes:NULL];


        // copy copy original to presentationfiles directory
        NSString *originalPath = [originalFilesDirectoryPath stringByAppendingPathComponent:curFileName];
        [fileManager copyItemAtPath:filePath toPath:originalPath error:NULL];

        [originalFiles removeLastObject];

        [pool drain];

        [self processCacheItems:originalFiles]; // recursion
    }

}

【问题讨论】:

  • 转到构建设置并启用“运行静态分析器”。
  • 使用仪器工具查找内存泄漏的位置..
  • @iAmitWagh 我在 Instruments 中看不到它,使用 Memory Leaks.. 在“Allocations”中它看起来也不错..
  • @WTP。我已启用“运行静态分析器”我现在可以看到什么?在哪里?
  • 我在您的代码中看不到任何明显的泄漏,但是使用递归并在数组为空时释放数组并不是组织它的好方法。你为什么不遍历数组然后释放它呢? processCacheItems: 的方法名称并不表示它将释放您提供给它的参数。

标签: objective-c ios nsfilemanager


【解决方案1】:

感谢您的提示。

我喜欢,问题不是泄漏,而是在“resizedImageWithContentMode:”中缩小大图像时内存分配太大,导致应用程序崩溃。

我更改了图像缩放以使用图像 I/O 框架。 现在它工作正常。

【讨论】:

    【解决方案2】:

    更新:这个答案已经过时了。如果您使用的是 ARC,请忽略它。

    NSFileManager 是如何分配的?

    我经历过通过 + defaultManager 方法分配它,该方法已被弃用,会产生内存泄漏(或者 Instruments 这么说,Instruments 有时会报告没有内存泄漏的地方)。

    一般情况下,你应该用[[NSFileManager alloc] init]分配它,当你不再需要它时释放它。

    【讨论】: