使用AFNetworking依次下载图像 [英] Download images in order with AFNetworking

查看:213
本文介绍了使用AFNetworking依次下载图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用AFNetworking依次下载图像? 按顺序排列,我的意思是按顺序执行成功块。

How do you download images in order with AFNetworking? An by "in order", I also mean executing the success blocks in order.

最初,我认为这样做会足以使用 NSOperationQueue 并将每个 AFImageRequestOperation 设置为下一个的依赖项。像这样:

Initially I thought it would be enough to use a NSOperationQueue and set each AFImageRequestOperation as a dependency of the next one. Like this:

- (void) downloadImages
{
    { // Reset
        [_downloadQueue cancelAllOperations];
        _downloadQueue = [[NSOperationQueue alloc] init];
        _images = [NSMutableArray array];
    }
    AFImageRequestOperation *previousOperation = nil;
    for (NSInteger i = 0; i < _imageURLs.count; i++) {
        NSURL *URL = [_imageURLs objectAtIndex:i];
        NSURLRequest *request = [NSURLRequest requestWithURL:URL];
        AFImageRequestOperation *operation = [AFImageRequestOperation 
                                              imageRequestOperationWithRequest:request 
                                              imageProcessingBlock:nil 
        success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
            [_images addObject:image];
            NSLog(@"%d", i);
        } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {}];

        if (previousOperation) {
            [operation addDependency:previousOperation];
        }
        previousOperation = operation;

        [_downloadQueue addOperation:operation];
    }
}

这将打印 i 依次下载图像。但是,当请求已经被缓存时,成功块将被无序处理。我怀疑这是 NSOperation 的限制,而不是AFNetworking。

This prints i in order when the images are downloaded. However, when the requests are already cached, the success blocks are processed out of order. I suspect this is a NSOperation limitation, not AFNetworking.

我错过了什么吗?

推荐答案

您的解决方案可以正常工作,这是另一种解决方法:


为了完美 UX,您应该并行发出所有操作并按顺序处理图像(如果不需要,请不要等待)。

(错误处理在这里有所不同)

您可以尝试这样做(未经测试,您可以更好地设计模型[不只是使用像这样的数组]):

Your solution will work fine, here is another way to do it:

For the "perfect" UX you should issue all operations in parallel and process images by order as they come (don't wait if you don't have to).
(error handling is done differently here)
You could try this (untested, and you can better design the model [don't just use arrays like this]):

- (void) processImage:(UIImage*)image
{
    //do something with the image or just [_images addObject:image]
}

- (void) downloadImages
{
    { // Reset
        [_downloadQueue cancelAllOperations];
        _downloadQueue = [[NSOperationQueue alloc] init];
    }

    __block NSMutableArray* queue = [[NSMutableArray alloc] initWithCapacity:[_imageURLs count]];

    for (NSURL* url in _imageURLs) {
        __block NSLock* lock = [[NSLock alloc] init];
        __block NSMutableArray* container = [NSMutableArray new];
        [lock lock];
        [queue addObject:@[lock,container,url]];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        void(^compBlock)(NSURLRequest *request,
                         NSHTTPURLResponse *response,
                         UIImage *image) = ^(NSURLRequest *request,
                                             NSHTTPURLResponse *response,
                                             UIImage *image)
        {
            [container addObject:image];
            [lock unlock];
        };
        NSOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request
                                                                      imageProcessingBlock:nil
                                                                                   success:compBlock
                                                                                   failure:compBlock];
        [_downloadQueue addOperation:operation];
    }

    __block __weak id weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        for (NSArray* arr in queue) {
            NSLock* lock = arr[0];
            [lock lock];
            NSMutableArray* container = arr[1];
            if ([container count]) {
                [weakSelf processImage:container[0]]; //might want to call this on main thread
            } else {
                //error on url = arr[2]
            }
            [lock unlock];
        }
    });    
}

这篇关于使用AFNetworking依次下载图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆