滚动时的感觉滞后,同时从后台线程中的资产加载全屏图像

swa*_*ang 2 iphone lag grand-central-dispatch ios alasset

这是事情:我有一个滚动视图,它为用户照片的全屏图像做了延迟加载:

[self.assetsLibrary assetForURL:[NSURL URLWithString:[[self.assets objectAtIndex:index] objectForKey:@"asset_url"]]
    resultBlock:^(ALAsset *asset) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            CGImageRef cgImage = asset.defaultRepresentation.fullScreenImage;
            UIImage *image = [UIImage imageWithCGImage:cgImage];
            dispatch_async(dispatch_get_main_queue(), ^{
                imageView.image = image;
            });
        });
                    }
failureBlock:^(NSError *error) {
    NSLog(@"error");
}];
Run Code Online (Sandbox Code Playgroud)

我知道加载全屏图像是很昂贵的,所以我把它放到后台线程中,但是当我进行滚动时它仍然是滞后的.即使我改变它仍然滞后:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                            CGImageRef cgImage = asset.defaultRepresentation.fullScreenImage;
                            UIImage *image = [UIImage imageWithCGImage:cgImage];
                            imageView.image = image;
                            dispatch_async(dispatch_get_main_queue(), ^{
                            });
                        });
Run Code Online (Sandbox Code Playgroud)

显然,在主队列中没什么可做的,但是在我评论该行之前它仍然滞后:

// CGImageRef cgImage = asset.defaultRepresentation.fullScreenImage;
Run Code Online (Sandbox Code Playgroud)

所以我很困惑,当我使用GCD时有什么问题吗?有人可以帮我解释一下吗?任何事情都会有所帮助.

感谢你们.

UPDATE

To @Fogmeister:照片的大小是全屏尺寸,actuel imageView大小约为一半.甚至我评论这一行:"imageView.image = image;" 它仍然滞后.这意味着它不是来自调整大小.我知道时间在哪里,这里:"asset.defaultRepresentation.fullScreenImage;".当我评论它,一切都很好,没有更多的滞后. 所以,我不明白的是,我已经把它放在后台线程......

swa*_*ang 5

好的,最后我解决了问题:

而不是直接获取图像

asset.defaultRepresentation.fullScreenImage
Run Code Online (Sandbox Code Playgroud)

我使用Apple的Exemple PhotosByLocation(下面的代码)中的方法来获取BG线程中的图像.滚动时效果很好,不再有滞后.但我仍然感到困惑,我不确切知道为什么.如果有人能向我解释,我很感激.

- (UIImage *)fullSizeImageForAssetRepresentation:(ALAssetRepresentation *)assetRepresentation {

UIImage *result = nil;
NSData *data = nil;

uint8_t *buffer = (uint8_t *)malloc(sizeof(uint8_t)*[assetRepresentation size]);
if (buffer != NULL) {
    NSError *error = nil;
    NSUInteger bytesRead = [assetRepresentation getBytes:buffer fromOffset:0 length:[assetRepresentation size] error:&error];
    data = [NSData dataWithBytes:buffer length:bytesRead];

    free(buffer);
}

if ([data length]) {
    CGImageSourceRef sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef)data, nil);

    NSMutableDictionary *options = [NSMutableDictionary dictionary];

    [options setObject:(id)kCFBooleanTrue forKey:(id)kCGImageSourceShouldAllowFloat];
    [options setObject:(id)kCFBooleanTrue forKey:(id)kCGImageSourceCreateThumbnailFromImageAlways];
    [options setObject:(id)[NSNumber numberWithFloat:640.0f] forKey:(id)kCGImageSourceThumbnailMaxPixelSize];
    //[options setObject:(id)kCFBooleanTrue forKey:(id)kCGImageSourceCreateThumbnailWithTransform];

    CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(sourceRef, 0, (__bridge CFDictionaryRef)options);

    if (imageRef) {
        result = [UIImage imageWithCGImage:imageRef scale:[assetRepresentation scale] orientation:(UIImageOrientation)[assetRepresentation orientation]];
        CGImageRelease(imageRef);
    }

    if (sourceRef) CFRelease(sourceRef);
}

return result;
}
Run Code Online (Sandbox Code Playgroud)