从 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 从“我的照片流”加载图像

如何从 PHAsset 获取图像 URL?是不是可以使用 PHAsset URL 将图像保存到文档目录?

在核心数据中保存 PHAsset?

从 PHAsset 确定图像 MB 大小

在不加载 PHAsset us 照片库的情况下获取所有图像本地标识符/文件路径