ios - for 循环内的 NSURLConnection 异步请求无法正确下载 NSData (Swift)

标签 ios swift asynchronous nsurlconnection nsdata

我编写了一个名为 Movie 的类,其初始化程序采用整数“id”来从 Rotten Tomatoes API 检索数据:

init(id: Int) {
    let movieURL = NSURL(string: "http://api.rottentomatoes.com/api/public/v1.0/movies/\(id).json?apikey=\(apiKey)")!

    NSURLConnection.sendAsynchronousRequest(NSURLRequest(URL: movieURL), queue: NSOperationQueue()) { (response, movieData, error) -> Void in
        var movieJson = NSJSONSerialization.JSONObjectWithData(movieData, options: NSJSONReadingOptions.MutableContainers, error: nil) as? [String: AnyObject]

        self.id = self.idFromMovieJson(movieJson)
        self.title = self.titleFromMovieJson(movieJson)
        // ...

        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            self.delegate!.movieDidDownload(self)
        })
    }        
}

如果我用正确的 ID 实例化一个 Movie 对象,一切都会按预期进行。这是我在另一个类上写的:

var movie = Movie(id: 771351912)
movie.delegate = self

func movieDidDownload(movie: Movie) {
    println(movie.title)
}

这是输出:

Optional("Interstellar")

但是,当我尝试像这样在 for 循环中实例化 Movie 对象时:

let ids = [771351912, 771380953, 771041011, 13863, 12490, 771311818, 771321699, 11691]
for id in ids {
    var movie = Movie(id: id)
    movie.delegate = self
}

打印结果不是很令人鼓舞:

Optional("Super 8") 
Optional("Interstellar") 
Optional("Pulp Fiction")
nil 
Optional("The Nightmare Before Christmas") 
nil
nil
Optional("Nightcrawler")

最糟糕的是,每次我构建和运行我的代码时,println() 的输出都不同:

Optional("Interstellar")
Optional("Pulp Fiction")
Optional("Super 8")
Optional("Nightcrawler")
Optional("The Nightmare Before Christmas")
nil
nil
nil

我什至尝试创建具有不同名称的不同 NSOperationQueues 以在 NSURLConnection.sendAsynchronousRequest() 方法中使用,但这也没有成功:

var queue = NSOperationQueue()
queue.name = "\(id)"

我猜这个问题与我同时发送太多请求有关。我已将 sleep(1) 放在 ids for 循环中,它实际上正确地打印了电影标题。

有人知道如何在 for 循环中异步发出多个请求吗?

最佳答案

swift println() 函数是异步的,不能保证传递的顺序,所以这样使用可能会得到各种困惑的结果。

我建议改为使用 NSLog(),因为这会提供更一致的结果。

此外,为每个请求创建一个新的一次性 NSOperationQueue() 似乎不是一个好主意,因为队列可能在操作执行之前被释放。尝试使用 NSOperationQueue.mainQueue() 代替。

作为一个额外的好处,对每个请求使用单个队列而不是不同的队列应该确保电影按照您请求的顺序下载。

关于ios - for 循环内的 NSURLConnection 异步请求无法正确下载 NSData (Swift),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27425587/

相关文章:

iOS 11 UITableView 错误

ios - 在 UISwipeActionsConfiguration iOS 11 中更改文本和图像的颜色 - Xamarin/Swift

swift - 如何以编程方式在 swift 3 中制作全屏按钮

ios - UITextView .isEmpty 不适用于键盘发送 Swift

asynchronous - 在oneshot channel : object safety error中使用 `DeserializedOwned`特征

ios - HKObserverQuery 失败,授权未确定

ios - 如何将我的 Swift IOS 应用程序与 Pinterest 集成?

swift - 在 Swift 中为引用的 C 结构中的属性设置值

c# - 为什么从给定的订阅者抛出时从未调用过OnError回调?

javascript - 像 Rails 一样,在 Node.js (node-orm) 中链接模型关系