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 的值,这是罪魁祸首。我把它改成了lCgSize
,lCgSize = CGSizeMake(105, 105);
解决了这个问题。
根据文档 PHImageManagerMaximumSize
当您使用 PHImageManagerMaximumSize 选项时,Photos 提供 可用于资产的最大图像,无需缩放或裁剪。 (也就是说,它忽略了 resizeMode 选项。)
所以,这就解释了问题所在。我相信如果是单个图像,应该没有问题,但如果是多个图像,设备会耗尽内存。
【讨论】:
以上是关于PHImageManager 在许多图像请求后崩溃的主要内容,如果未能解决你的问题,请参考以下文章
PHImageManager 中的图像数据与保存为资产的图像数据不同
使用 PHImageManager 时,PHAsset 返回 UIImage 的 nil 值
HighQualityFormat 的 PHImageManager.requestImageForAsset 从不调用 resultHandler