PHImageManager 在许多图像请求后崩溃

Posted

技术标签:

【中文标题】PHImageManager 在许多图像请求后崩溃【英文标题】:PHImageManager crashing after many image requests 【发布时间】:2014-11-12 00:00:27 【问题描述】:

我正在尝试使用PHAssetMediaTypeImage 获取所有用户PHAsset,然后遍历它们,一次获得一个对应的UIImages。我的 iPhone 5 上有大约 2k 张照片,这段代码在遍历 587 张照片后崩溃。

PHFetchResult *fr = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];

PHImageManager *manager = [PHImageManager defaultManager];
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.synchronous = YES;
__block int i = 0;
for (PHAsset *result in fr)


    [manager requestImageForAsset:result targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage *image, NSDictionary *info) 
        NSLog(@"%d", i);
        i++;
    ];

异常读取 EXC_BAD_ACCESS(代码=1,地址=0x0)。任何为我指明正确方向的帮助将不胜感激。

【问题讨论】:

如果你再拍一张照片,它仍然在 587 处失败,还是在 588 处崩溃?你为什么要这样做?如果您提供更多背景信息,我们或许可以提供另一种方法,因为这听起来不是最佳方法。 @Stephen 你明白了吗?我看到了同样的问题,我很想听听你的发现。如果您没有答案,发布我认为的崩溃线程的堆栈跟踪会很有用 我无法弄清楚。我已经把那个项目搁置了一段时间,但我想当我回到它时,我会采取不同的方法并批量处理图像,除非 Apple 到那时修复了这个错误。 【参考方案1】:

关闭这个循环。在 for 循环完成之前,图像不会被释放,因此您需要在循环的每次迭代后放置一个 @autoreleasepool 来排空池,就像这样

PHFetchResult *fr = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];
PHImageManager *manager = [PHImageManager defaultManager];
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.synchronous = YES;
__block int i = 0;
for (PHAsset *result in fr)

    @autoreleasepool 
    [manager requestImageForAsset:result targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage *image, NSDictionary *info) 
            NSLog(@"%d", i);
            i++;
        ];
    

【讨论】:

【参考方案2】:

在这行代码中发现了我的问题

   PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: PHImageManagerMaximumSize, contentMode: .AspectFill, options: nil, resultHandler: (result, info) in cell.setThumbnailImage(result)
    )

参数 targetSize 传递了 PHImageManagerMaximumSize 的值,这是罪魁祸首。我把它改成了lCgSizelCgSize = CGSizeMake(105, 105); 解决了这个问题。

根据文档 PHImageManagerMaximumSize

当您使用 PHImageManagerMaximumSize 选项时,Photos 提供 可用于资产的最大图像,无需缩放或裁剪。 (也就是说,它忽略了 resizeMode 选项。)

所以,这就解释了问题所在。我相信如果是单个图像,应该没有问题,但如果是多个图像,设备会耗尽内存。

【讨论】:

以上是关于PHImageManager 在许多图像请求后崩溃的主要内容,如果未能解决你的问题,请参考以下文章

PHImageManager 中的图像数据与保存为资产的图像数据不同

使用 PHImageManager 时,PHAsset 返回 UIImage 的 nil 值

ios13使用PHImageManager获取原始图像

HighQualityFormat 的 PHImageManager.requestImageForAsset 从不调用 resultHandler

如何在不重新保存的情况下从 iCloud 下载图像?

将PHAsset转换为UIImage后设置UiButton图像