iOS UICollectionView Lazy Images性能问题

时间:2015-04-27 06:36:12

标签: ios objective-c uicollectionview lazy-loading uicollectionviewcell

iOS UICollectionView存在问题。我试图根据Apple示例懒惰加载集合视图图像:https://developer.apple.com/library/ios/samplecode/LazyTableImages/Introduction/Intro.html

我的UICollectionViewDataSource已实施:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:COLLECTION_VIEW_CELL_REUSE_IDENTIFIER forIndexPath:indexPath];

    if (!cell.record)
    {
        cell.record = [self.dataSource objectAtIndex:indexPath.item];

        [self downloadThumbnailForItemAtIndexPath:indexPath];
    }

    return cell;
}

要下载缩略图,我正在调用私有方法:

- (void)downloadThumbnailForItemAtIndexPath:(NSIndexPath *)indexPath
{
    [self.model thumbnailForItemAtIndexPath:indexPath success:^(UIImage *thumbnail)
    {
        UICollectionViewCell *cell = [self.clipboardCollectionView cellForItemAtIndexPath:indexPath];

        cell.backgroundColor = [UIColor colorWithPatternImage:thumbnail];
    }

    failure:^(NSError *error)
    {        
        // Do thumbnail generation failure actions here!
    }];
}

模型中实现的缩略图生成方法是:

- (void)thumbnailForItemAtIndexPath:(NSIndexPath *)indexPath success:(void (^)(UIImage *thumbnail))success failure:(void (^)(NSError *error))failure;
{
    NSError *error;

    __block UIImage *thumbnail;

    NSURL *url = [WEB_SERVICE_URL stringByAppendingString:[NSString stringWithFormat:@"%d", indexPath.item]];

    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)
    {
        if (result == AVAssetImageGeneratorSucceeded)
        {
            thumbnail = [UIImage imageWithCGImage: image];

            success(thumbnail);
        }

        else
        {
            failure(error);
        }

    };

    CGSize maximumSize = CGSizeMake(COLLECTION_VIEW_CELL_WIDTH, COLLECTION_VIEW_CELL_HEIGHT);

    generator.maximumSize = maximumSize;

    [generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:time]] completionHandler:handler];
}

据我了解,这个生成过程应该在后台运行。然而,当我第一次向下滚动集合视图时,我会持续几秒钟来持续收集视图滞后。对于第二个滚动UICollectionViewCell,我们没有请求缩略图,因此没有滞后。

我的问题是:如何优化这个缩略图生成过程以避免这么大的滞后?

更新

根据评论,我已经在后台实施了加载:

UIApplication *application = [UIApplication sharedApplication];

__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^
{
    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
    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)
    {
        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;

    [generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:time]] completionHandler:handler];

    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
});

在此更新中没有滞后。然而,它只为最后UICollectionView行生成缩略图...

@Aju提出的解决方案,乍一看解决了我的问题。但只是乍一看。我的集合视图有一个resize选项。当我点击调整大小按钮,集合视图大小发生变化时,需要加载更多缩略图并且我有一个巨大的滞后。