7

我正在尝试创建一个视频库。

要显示视频,我使用的是UICollectionView. 每个UICollectionViewCell都有一个带有视频缩略图的背景。为了生成视频缩略图,我使用了一种具有逻辑的方法:

AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];

AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];

generator.appliesPreferredTrackTransform = YES;

CMTime time = CMTimeMakeWithSeconds(0,15);

AVAssetImageGeneratorCompletionHandler handler = ^(CMTime timeRequested, CGImageRef image, CMTime timeActual, AVAssetImageGeneratorResult result, NSError *error)
{
    NSLog(@"handler^()");

    if (result == AVAssetImageGeneratorSucceeded)
    {
        thumbnail = [UIImage imageWithCGImage: image];

        success(thumbnail);
    }

    else
    {
        failure(error);
    }
};

CGSize maximumSize = CGSizeMake(CLIPBOARD_COLLECTION_VIEW_CELL_WIDTH, CLIPBOARD_COLLECTION_VIEW_CELL_HEIGHT);

generator.maximumSize = maximumSize;

NSLog(@"generateCGImagesAsynchronouslyForTimes:");
[generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:time]] completionHandler:handler];

我注意到generateCGImagesAsynchronouslyForTimes它不能完全异步工作。此方法调用之间存在时间间隔。当我加载表格视图单元格时,这会导致很大的延迟。如果我评论行[generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:time]] completionHandler:handler],则没有可见的滞后(也没有图像)。

我该如何解决这个性能问题?

4

2 回答 2

3

AVAssetImageGeneratorCompletionHandler不保证在主线程上调用该块:

与 AV Foundation 的并发编程

来自 AV Foundation 的调用(块调用、键值观察器和通知处理程序)不能保证在任何特定线程或队列上进行。相反,AV Foundation 在执行其内部任务的线程或队列上调用这些处理程序。您负责测试调用处理程序的线程或队列是否适合您要执行的任务。如果不是(例如,如果您想更新用户界面并且标注不在主线程上),您必须将任务的执行重定向到您识别的安全线程或队列,或者您为目的。

呼叫successfailure解决dispatch_async问题吗?

dispatch_async(dispatch_get_main_queue(), ^{
    if (success) {
        success();
    }
)};
于 2015-04-28T20:32:56.380 回答
0

有几种方法可以将异步图像生成请求重定向到另一个线程,其中一种是将 NSBlockOperation 中的函数封装到 NSOperationQueue 中,并将其底层队列设置为最适合您的应用程序的队列。

如果您不知道,最合适的队列应该相对容易猜到,因为那里只有几个选择。

于 2016-06-24T06:43:55.397 回答