首页 > 解决方案 > 使用单例快速获取数据

问题描述

我一直在使用 URLSession.shared.dataTask从我的应用程序执行 API 调用。我只是对单例的功能感到困惑。据我了解,只有一个单例实例,在这种情况下只有一个urlSession. 现在下面的代码片段将导致 3 个异步调用,但是,我们只有一个dataTask. 这是否意味着我们在这里看到了串行行为?

["1","2","3"].forEach {
     loadImage(url: $0) {
     print("image Successfully cached")
      }
}

   func loadImage(url:String, _ completion: @escaping ()->()){
       URLSession.shared.dataTask(with: URL(string: url)!) {[weak self] (data,response,error) in
           print("starting \(url) Thread.current")
           Thread.sleep(forTimeInterval: Double.random(in: 0...3))
           if let response = response as? HTTPURLResponse , response.statusCode == 200 {
               let image = UIImage(data: data!)
               self?.imageCache.setObject(image!, forKey: url as NSString)
               completion()
           } else {
               print("finishing \(url) Thread.current")
               completion()
           }
       }.resume()
   }

我的操场的输出

starting 1 <NSThread: 0x6000037e8ec0>{number = 7, name = (null)}
finishing 1 <NSThread: 0x6000037e8ec0>{number = 7, name = (null)}
image Successfully cached
starting 2 <NSThread: 0x6000037d3380>{number = 4, name = (null)}
finishing 2 <NSThread: 0x6000037d3380>{number = 4, name = (null)}
image Successfully cached
starting 3 <NSThread: 0x6000037d3380>{number = 4, name = (null)}
finishing 3 <NSThread: 0x6000037d3380>{number = 4, name = (null)}
image Successfully cached

标签: iosswiftconcurrency

解决方案


您看到的是串行调用的完成处理程序。网络请求在多个线程上运行,但它们汇聚到一个点以执行其完成处理程序。

delegateQueue如果您不使用shared会话https://developer.apple.com/documentation/foundation/urlsession/1411597-init ,则处理程序在 URLSessionConfiguration 中运行,指定为

每次调用时Thread.sleep,这都会完全阻止队列执行,它不会释放队列以供队列中的其他项目运行,因为默认情况下,队列在单个线程上一次运行一个作业。

在没有看到网络请求的情况下,这可能只是一个巧合,所有 3 个请求都按顺序完成,并且它们的完成处理程序以相同的顺序放入队列中。


推荐阅读