如何确保收到的NSURLSession响应的顺序与请求的顺序相同?

时间:2015-08-05 13:55:06

标签: ios swift

我在循环中做了几个NSURLSession请求。我想以与创建任务相同的顺序存储响应的结果。但是,由于完成处理程序在一个单独的线程中运行,有时会发生在对第一个任务的响应之前收到对第二个任务的响应。

如何确保我的响应与启动任务的顺序相同?

SQLiteOpenHelper

3 个答案:

答案 0 :(得分:1)

虽然我不鼓励要求以特定顺序接收回复的行为,但您可以将回复(无论收到的顺序如何)整理成已知的顺序。

receivedData数组应初始化,其容量应与将要发出的请求数相匹配:

var receivedData = [String](count: urlsAsString.count, repeatedValue: "")

然后,当您收到响应时,由于您位于可以访问请求index的块中,您可以将响应数据直接添加到receivedData数组的索引中:< / p>

receivedData[index] = result as (String)

完整代码如下:

var receivedData = [String](count: urlsAsString.count, repeatedValue: "")

for index in 0 ... urlsAsString.count-1 {
    let myUrl = NSURL(string: urlsAsString[index])
    var request = NSMutableURLRequest(URL: myUrl!)
    // here I also set additional parameters (HTTPMethod, ...)

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            responseData, response, error in

        // here I handle the response
        let result = ...
        dispatch_async(dispatch_get_main_queue()) {
            // Insert the result into the correct index
            receivedData[index] = result
        }
    }
    task.resume()
}

答案 1 :(得分:1)

因为您知道http请求的确切数量。

您可以创建一个大小为urls.count的数组,然后将结果设置为完成处理程序,对应于每个循环中的索引。

receivedData = [String](count: urls.count, repeatedValue: "No Data")
for (index,url) in enumerate(urls){
    let url = NSURL(string: url)!
    let task = NSURLSession.sharedSession().dataTaskWithURL(url){ data, response, error in
        if error != nil{
            self.receivedData[index] = "error: \(error.localizedDescription)"
            return
        }
        let result = ...
        dispatch_async(dispatch_get_main_queue()) {
            self.recivedData[index] = "\(result)"
        }
    }
    task.resume()
}

答案 2 :(得分:0)

实际上,无法确定回复的顺序。 有两种解决方法:

  1. 一个接一个地发送请求,这意味着在返回上一个响应后发送下一个请求。您可以使用ReactiveCocoa使代码更优雅。或者使用我编写的网络库STNetTaskQueue,有一个STNetTaskChain可以一个接一个地处理请求。

  2. 并行发送请求(就是您现在正在做的事情),并使用NSDictionary跟踪请求和响应,在所有请求完成后,按原始顺序组合响应。

  3. 希望这有帮助!