ios - 如何在 iOS 中按特定顺序异步下载文件?

标签 ios json multithreading asynchronous

我的 iPhone 应用程序使用 NSURLRequest 向我的网站发出异步请求。

响应是包含 10 个图像 URL 的 JSON。当我收到异步响应时,我想使用循环下载 10 个文件,创建 UIImage 对象的 NSMutableArray

我尝试使用 NSData dataWithContentsOfURL 方法执行此操作,它可以工作但不是异步的,因此用户界面被阻止。

如果我尝试在此异步方法的响应中使用 NSURL 异步方法,当我收到 10 个带有图像的响应时,我无法知道图像是否已按顺序下载,在我的应用程序中,顺序很重要。

在不阻塞 UI 的情况下按顺序下载文件的解决方案是什么?

我的代码:

// Create the request.
NSString *advertURL = [NSString stringWithFormat: @"http://www.myURL"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:advertURL]
    cachePolicy:NSURLRequestUseProtocolCachePolicy
    timeoutInterval:60.0];

// Create url connection and fire request
imagesConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

当我收到回复时:

//decode json with the urls   
NSArray* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

//star the loop to downloading the ten images
for (int i=0; i<10; i++) {
    //find image[i] url from json
    NSString *fullImage_URL = json[i][@"url"];

    //download image synchronously (this blocks the UI!!)
    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fullImage_URL]];

    //insert image in the array
    arrayImages[i] = [UIImage imageWithData:data];
}

然后,当我确定数组有 10 张图像并且它们是有序的时,我可以开始在屏幕上显示图像。

最佳答案

与其处理 JSON 数组然后在主线程上循环并获取所有这些图像,不如在后台线程上执行。在后台,运行循环,最后,调用 main 上的另一个方法来发出完成任务的信号。

//star the loop to downloading the ten images ... in the background

dispatch_queue_t currentQueue = dispatch_get_current_queue();
dispatch_retain(currentQueue);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0, ^(void) {

    for (int i=0; i<10; i++) {

        //find image[i] url from json

        NSString *fullImage_URL = json[i][@"url"];

        //download image synchronously (this blocks the UI!!)


        NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fullImage_URL]];

        //insert image in the array

        arrayImages[i] = [UIImage imageWithData:data];

    }

    // Return to main queue
    dispatch_async(currentQueue, ^{ 

        // process arrayImages now

    });

    dispatch_release(currentQueue);
});

要阅读有关调度队列的更多信息,请查看:

https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html#//apple_ref/doc/uid/TP40008091-CH102-SW1

还有许多其他方法可以做到这一点。就个人而言,我自己喜欢使用 NSNotificationCenter 和 OBSERVER 模式。

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html

关于ios - 如何在 iOS 中按特定顺序异步下载文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20572794/

相关文章:

linux - 调用线程构造函数时出现段错误

.net - .NET中的生产者消费者链和线程调度

ios - 如何使 REFrostedViewController 与 UINavigationController 一起工作

javascript - 如何为所有 res.json() 表达添加时间戳

arrays - 如何将 Node js中的格式数组从1个字符串更改为另一个对象

android - 将数据附加到现有的 JSON 文件

ios - 解析为 "Login with Facebook"的 FBLoginView

ios - 应用程序处于后台时的通知;

ios - 在哪里可以找到 iOS8 蓝牙的文档

python - 如果 Python 进程在特定时间内未完成,则终止它?