我正在使用以下代码从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];
}
});
}
}];
});
}
有什么建议吗?
只有一个想法,在删除进度HUD并显示图库之前,看起来您正在加载阵列中的所有图像。由于图像的数量可能非常大并且假设您正在使用集合视图或类似图像,因此在显示任何内容之前这是一个相当大的开销。
我不久前做了类似的事情,而不是循环遍历数组并预先加载所有内容,我让单元格在需要时请求图像。这使得它非常快速和高效,因为单元格可以立即显示加载图标,然后在图像可用时翻转到图像。效率来自仅加载用户实际将要看到的图像。
为了使性能高效,并且通过高性能,我的意思是我可以在没有显示冻结的情况下以我喜欢的速度滚动,每个单元格首先检查内存缓存中的图像,然后在后台线程上触发对图像的请求。
返回图像时,单元格会将其添加到内存缓存中,然后如果单元格没有被重用于其他图像(由于快速滚动),它将显示图像。
此外,我还使用NSCache作为内存缓存,这样如果应用程序开始使用大量内存,图像将自动删除并在下次单元格需要时重新加载。
摘要是使用内存感知缓存,只加载您实际需要的内容。