高内存使用情况循环通过PHAssets并调用requestImageForAsset [英] High memory usage looping through PHAssets and calling requestImageForAsset

查看:1916
本文介绍了高内存使用情况循环通过PHAssets并调用requestImageForAsset的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用图片选择器库,允许用户从他们的照片库中选择许多图像。它们以 PHAssets 的数组形式返回。然后,我想将所有 PHAssets 转换为 UIImages 并将它们写入应用程序的存储空间。

I'm using an image picker library to allow the user to select many images from their photo library. They are returned as an array of PHAssets. Then, I want to convert all the PHAssets to UIImages and write them to the app's storage.

目前,我正在遍历所有资产并同步调用 requestImageForAsset 。我的问题是,当运行此循环时,内存使用量会出现非常高的峰值(30个图像,最高可达130MB)。我想阻止这一点。

At the moment, I'm looping through all the assets and calling requestImageForAsset synchronously. My issue is that there is incredibly high memory usage spike when this loop is being run (with 30 images, it spikes up to 130MB). I would like to prevent this.

这是我的代码:

for(PHAsset *asset in self.assets) {
        NSLog(@"started requesting image %i", i);
        [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:[self imageRequestOptions] resultHandler:^(UIImage *image, NSDictionary *info) {
            dispatch_async(dispatch_get_main_queue(), ^{
                assetCount++;
                NSError *error = [info objectForKey:PHImageErrorKey];
                if (error) NSLog(@"Image request error: %@",error);
                else {
                    NSString *imagePath = [appDelegate.docsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%i.png",i]];
                    NSData *imageData = UIImagePNGRepresentation(image);
                    if(imageData) {
                        [imageData writeToFile:imagePath atomically:YES];
                        [self.imagesArray addObject:imagePath];
                    }
                    else {
                        NSLog(@"Couldn't write image data to file.");
                    }
                    [self checkAddComplete];
                    NSLog(@"finished requesting image %i", i);
                }
            });
        }];
    i++;
}

根据日志,我看到所有开始请求图片x 首先调用,然后调用所有完成块(完成请求图像x)。我认为这可能会导致内存问题。确保在释放这些资源并转移到下一次迭代之前调用每次迭代的完成块可能会减少内存密集度。我该怎么做?

Based on the logs, I see that all of the "starting requesting image x" are called first, then all of the completion blocks ("finished requesting image x"). I think that this might be contributing to the memory issue. It would probably be less memory intensive to ensure that the completion block for each iteration is called before freeing those resources and moving to the next iteration. How can I do this?

推荐答案

请使用 autoreleasepool 进行内存管理。

for(PHAsset *asset in self.assets) {
    // This autorelease pool seems good (a1)
    @autoreleasepool {
        NSLog(@"started requesting image %i", i);
        [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:[self imageRequestOptions] resultHandler:^(UIImage *image, NSDictionary *info) {
            dispatch_async(dispatch_get_main_queue(), ^{
                //you can add autorelease pool here as well (a2)
                @autoreleasepool {
                    assetCount++;
                    NSError *error = [info objectForKey:PHImageErrorKey];
                    if (error) NSLog(@"Image request error: %@",error);
                    else {
                        NSString *imagePath = [appDelegate.docsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%i.png",i]];
                        NSData *imageData = UIImagePNGRepresentation(image);
                        if(imageData) {
                            [imageData writeToFile:imagePath atomically:YES];
                            [self.imagesArray addObject:imagePath];
                        }
                        else {
                            NSLog(@"Couldn't write image data to file.");
                        }
                        [self checkAddComplete];
                        NSLog(@"finished requesting image %i", i);
                    }
                } //a2 ends here
            });
        }];
        i++;
    } // a1 ends here
}

这篇关于高内存使用情况循环通过PHAssets并调用requestImageForAsset的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆