从PHAsset加载图像非常慢

时间:2018-09-04 06:09:08

标签: ios objective-c phasset

我正在使用以下代码从PHAsset获取图像和AVAsset。这是代码中的两个数组:

  1. galleryArr:存储图像以供收藏夹视图。

  2. mutableDataArr:存储要存储在服务器上的图像(用于图像资产)和视频(用于AVAset)

从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];
                                }



                            });
                        }
                    }];
});


}

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

一个想法,看来您是在从阵列中加载所有图像,然后再删除进度HUD并显示图库。由于图像数量可能非常大,并且假定您使用的是集合视图或类似视图,因此在显示任何内容之前,这是相当大的开销。

我前一阵子做了这样的事情,而不是循环遍历数组并预先加载所有内容,而是让单元在需要它们时请求图像。这使得它非常快速和高效,因为单元格可以立即显示带有加载图标,然后在可用时翻转到图像。效率来自仅加载用户实际上将要看到的图像。

要使性能表现出色,我的意思是说我可以按照自己喜欢的速度滚动而不会冻结显示屏,每个单元首先会在内存缓存中检查图像,然后在后台线程上触发图像请求。

返回图像时,单元会将其添加到内存中的缓存中,然后,如果该单元未被重用于其他图像(由于快速滚动),它将显示该图像。

此外,我还使用了一个NSCache作为内存中的缓存,这样,如果该应用开始使用大量内存,则下一次一个单元需要图像时,图像将被自动删除并重新加载。

摘要是使用内存感知缓存,并且仅加载您实际需要的内容。