【问题标题】:Saving big images one after another memory deallocation on iOS在iOS上一个接一个地保存大图像内存释放
【发布时间】:2012-03-06 19:49:14
【问题描述】:

在将大量大图像(来自相机)循环保存到文件系统时,我遇到了一个奇怪的问题。

如果我在每个循环中放置[NSThread sleepForTimeInterval:1.0];,那么在每次图像处理后都会释放内存。但是如果没有这个睡眠间隔,内存分配会增加,最终导致应用崩溃......

有人可以解释一下如何避免这种情况或在每次循环后释放内存吗?

顺便说一句,我正在 iOS 5 上开发...

这是我的代码:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    for (NSDictionary *imageInfo in self.imageDataArray) {

        [assetslibrary assetForURL:[NSURL URLWithString:imageUrl] resultBlock:^(ALAsset *asset) {
            CGImageRef imageRef = [[asset defaultRepresentation] fullResolutionImage];
            if (imageRef) {
                [sharedAppSettingsController saveCGImageRef:imageRef toFilePath:filePath];
                imageRef = nil;
                [NSThread sleepForTimeInterval:1.0];
                //CFRelease(imageRef);
            }
        } failureBlock:^(NSError *error) {
            NSLog(@"booya, cant get image - %@",[error localizedDescription]);
        }];

    }

    // tell the main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        //do smth on finish
    });
});

这是将CGImage保存到FS的方法:

- (void)saveCGImageRef:(CGImageRef)imageRef toFilePath:(NSString *)filePath {
    @autoreleasepool {
        CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:filePath];
        CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypeJPEG, 1, NULL);
        CGImageDestinationAddImage(destination, imageRef, nil);

        bool success = CGImageDestinationFinalize(destination);
        if (!success) {
            NSLog(@"Failed to write image to %@", filePath);
        }
        else {
            NSLog(@"Written to file: %@",filePath);
        }
        CFRelease(destination);
    }
}

【问题讨论】:

  • 您是否将循环包装在 @autorelease{} 块中?
  • 我已经在循环内外包装了代码,没有任何效果。应用程序仍然消耗超过 20MB 的内存而不是崩溃。还有什么要寻找的吗?
  • 如果我做错了,有人可以看看代码吗?

标签: ios image memory memory-management


【解决方案1】:

问题是您在 for 循环中调用了“assetForURL”。此方法将开始同时在单独的线程上加载所有图像。您应该开始加载 1 张图像,并在完成块中继续加载下一张。我建议你使用某种递归。

【讨论】:

    【解决方案2】:

    我刚刚发现问题不在于 saveImageRef 方法,而在于 ALAssetRepresentation 对象:

    CGImageRef imageRef = [[asset defaultRepresentation] fullResolutionImage];
    

    imageRef 在从照片库中读取每个原始图像后分配大量内存。这有点合乎逻辑。

    但我希望在每个循环结束时释放这个 imageRef 对象,而不是在 ARC 决定释放它时释放它。

    所以我在每次循环后尝试imageRef = nil;,但没有任何改变。

    有没有其他方法可以在每个循环结束时释放分配的内存?

    【讨论】:

      猜你喜欢
      • 2012-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多