从 PHAsset 加载图像非常慢
Posted
技术标签:
【中文标题】从 PHAsset 加载图像非常慢【英文标题】:Very slow to load images from PHAsset 【发布时间】:2018-09-04 06:09:07 【问题描述】:我正在使用以下代码从 PHAsset 获取图像和 AVAsset。这是代码中的两个数组:
galleryArr
:存储图片以供收藏视图。
mutableDataArr
:存储图片(用于图片资产)和视频(用于 AVAsset)上传到服务器
从 PHAssets 数组中获取所有图像非常慢。 我对此进行了谷歌搜索,大多数人说删除此行 [options setSynchronous:YES];但是如果我删除这一行,那么完成会被调用两次,并且数组会复制对象(因为对象会在完成内附加到数组中)。
for (int i = 0; i < assets.count; i++)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
options.resizeMode = PHImageRequestOptionsResizeModeExact;
[options setNetworkAccessAllowed:YES];
[options setSynchronous:YES];
PHImageManager *manager = PHImageManager.defaultManager;
PHVideoRequestOptions *videoOptions = [[PHVideoRequestOptions alloc] init];
videoOptions.networkAccessAllowed = YES;
__weak typeof(self) weakSelf = self;
if (assets[i].mediaType == PHAssetMediaTypeVideo)
[manager requestAVAssetForVideo:[assets objectAtIndex:i] options:videoOptions resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info)
if ([asset isKindOfClass:[AVURLAsset class]])
[weakSelf.mutableDataArr addObject:asset];
];
[manager requestImageForAsset:[assets objectAtIndex:i]
targetSize: CGSizeMake(1024, 1024) //PHImageManagerMaximumSize
contentMode:PHImageContentModeAspectFit
options:options
resultHandler:^(UIImage *image, NSDictionary *info)
if (image)
dispatch_async(dispatch_get_main_queue(), ^
if (assets[i].mediaType != PHAssetMediaTypeVideo)
[weakSelf.mutableDataArr addObject:image];
[galleryArr addObject:image];
if (i+1 == assets.count)
[SVProgressHUD dismiss];
[weakSelf.galleryCollectionView reloadData];
);
];
);
有什么建议吗?
【问题讨论】:
我的应用程序也有同样的问题,所以我在viewdidload
中创建了一个线程并在后台调用此函数。在完成块中,我在数组中添加图像,在我重新加载我的 collectionview 之后。
您获取的图像/视频可能来自 iCloud,因此需要更多下载时间。
@BadhanGanesh 不,这些不是来自 iCloud
@PratikPrajapati 我无法在 viewdidload 上添加此代码,因为这些资产是从 imagePicker 库中选择的。我只能在完成 imagePicker 时调用这个函数。
【参考方案1】:
想一想,看起来您正在从阵列中加载所有图像,然后再移除进度 HUD 并显示图库。由于图像的数量可能非常大,并且假设您使用的是集合视图或类似视图,因此在显示任何内容之前这是相当大的开销。
我不久前做过类似的事情,我没有循环遍历数组并预先加载所有内容,而是让单元格在需要时请求图像。这使得它非常快速和高效,因为单元格可以立即显示加载图标,然后在可用时翻转到图像。效率来自仅加载用户实际会看到的图像。
为了让事情变得高性能,我所说的高性能是指我可以尽可能快地滚动而不会冻结显示,每个单元格将首先检查内存缓存中的图像,然后在后台线程上触发对图像的请求.
当图像返回时,单元格会将其添加到内存缓存中,然后如果该单元格没有被重新用于不同的图像(由于快速滚动),它将显示该图像。
此外,我还为内存缓存使用了 NSCache,这样如果应用开始使用大量内存,图像会在下次单元需要时自动删除并重新加载。
总结就是使用内存感知缓存,只加载你真正需要的。
【讨论】:
图片和视频上传到服务器时是否应该循环浏览资产?以上是关于从 PHAsset 加载图像非常慢的主要内容,如果未能解决你的问题,请参考以下文章
照片框架 - 如何从 PHAsset 获取图像的 CLLocation?
在 iOS8 上使用 UIImagePicker 结果 URL 和 PHAsset 从“我的照片流”加载图像