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

时间:2013-12-13 17:46:15

标签: ios json multithreading asynchronous

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

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

我尝试使用方法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张图像并且它们按顺序排列时,我可以开始在屏幕上显示图像。

1 个答案:

答案 0 :(得分:2)

不是处理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