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

标签 iphone ios grand-central-dispatch lag alasset

事情是这样的: 我有一个 ScrollView ,它对用户照片的全屏图像进行了延迟加载:

[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");
}];

我知道加载全屏图像是昂贵的,所以我把它放在后台线程中,但是当我滚动时它仍然滞后。即使我这样改变它仍然落后:

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(), ^{
                            });
                        });

显然,在主队列中无事可做,但在我评论该行之前它仍然滞后:

// CGImageRef cgImage = asset.defaultRepresentation.fullScreenImage;

所以我很疑惑,是不是我用GCD的时候有问题? 有人可以帮我解释一下吗?任何事情都会有所帮助。

谢谢你们。

更新

致@Fogmeister:照片的大小是全屏大小,actuel imageView 大小大约是一半。即使我评论了这一行:“imageView.image = image;”它仍然滞后。这意味着它不是来自调整大小。我知道时间在哪里,在这里:“asset.defaultRepresentation.fullScreenImage;”。当我发表评论时,一切都很好,不再有延迟。 所以,我不明白的是,我已经把它放在后台线程中了...

最佳答案

好吧,我终于解决了问题:

而不是直接获取图片

asset.defaultRepresentation.fullScreenImage

我使用 Apple Example 中的方法 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;
}

关于iphone - 滚动时感觉滞后,同时从后台线程中的 Assets 加载全屏图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13942036/

相关文章:

iphone - 自定义 setter/getter 中的属性

iphone - iOS 5 - AFNetworking - 上传视频

ios - 使用 Gloss 框架的可解码、可编码、光泽一致性问题

ios 7 dequeueReusableCellWithIdentifier :forIndexPath method - does it need registerClass method

ios - RestKit:托管对象映射到一个普通的旧 Objective-C 对象中

multithreading - 调用performSelectorInBackground : from background thread

iphone - iPhone游戏咖啡馆音效

ios - IOS 10 或 11 上的 Ionic 3 header 高度

ios - 在 Web 服务异步回调上更新 UITableView

objective-c - 并行reduce算法实现