【问题标题】:Execute swift nsurlsession Tasks in serial order按顺序执行 swift nsurlsession 任务
【发布时间】:2019-12-06 05:15:54
【问题描述】:

我不知道如何一个一个地执行多个 NSUrlSession 任务。当第一个任务完成时启动第二个任务,当第二个任务完成时启动第三个任务等

例如,我想从网络服务下载多个文件。

我希望他们开始一个一个地下载。

例如文件:1.png、2.png、3.png

我希望按照我编写它们的相同顺序下载它们。

如何使用 NSUrlSession 做到这一点?

【问题讨论】:

  • 在前一个任务的完成处理程序中启动每个新任务。
  • @Gereon 这是错误的......我不是在寻找这种类型的解决方案。
  • 您可以构建一些数据结构并将其用作队列,以便您的完成处理程序检查队列并在有工作要做时执行下一次提取,但本质上@Gereon 是正确的
  • @Paulw11 我不能这样做。我从应用程序的不同部分执行这些下载任务或 http 请求。请提供不同的解决方案。也许有 DispatchQueue 的东西?
  • 您不能使用串行调度队列,因为task.resume 是非阻塞的并且调度工作是异步的。您知道数据任务完成的唯一点是在该数据任务的完成处理程序中。您需要构建自己的队列(数组可以)并让您的完成处理程序从数组中分派下一个项目。只要您使用单个队列实例,您从应用程序的不同部分执行此操作并不重要。请务必使用串行调度队列之类的东西来保护您的数组更新免受多个线程的影响

标签: ios swift grand-central-dispatch nsurlsession nsurlsessiontask


【解决方案1】:

两件事:

  1. 传统的 iOS 解决方案是将网络请求任务包装在异步 Operation 子类中(例如,如 this answer 的第 3 点中所述;请参阅 this answer 以了解该基础 AsynchronousOperation 的另一种排列方式)。只需将队列的maxConcurrentOperationCount 设置为1,您就可以串行/顺序下载图像。

  2. 但您真的不想这样做,因为您通过按顺序下载图像会付出巨大的性能损失。您应该按顺序执行网络请求的唯一时间是,如果您在准备下一个请求时绝对需要一个请求的响应(例如,“登录请求”检索令牌和使用令牌进行身份验证的后续请求)。

    但是,在处理一系列图像时,同时下载图像会快得多。将它们存储在字典(或其他任何东西)中:

    var imageDictionary: [URL: UIImage] = [:]
    

    然后:

    imageDictionary[url] = image
    

    然后,当您希望图像按原始 URL 数组的顺序排列时,您只需查找与 URL 关联的图像,例如:

    let sortedImages = urls.compactMap { imageDictionary[$0] }
    
  3. 或者,您可能会完全重新考虑预先下载一系列图像的概念。例如,如果这些是表格视图中的图像视图,您可能只使用第三方库,例如Kingfisher,并使用其UIImageView 方法setImage(with:)

    let url = URL(string: "https://example.com/image.png")
    imageView.kf.setImage(with: url)
    

    这让您完全摆脱了获取图像和管理缓存、内存不足警告等的麻烦。这种即时模式可以带来更高性能的用户界面。即使你真的想提前下载它们(有点极端,所以确保你真的需要这样做),像 Kingfisher 这样的库也可以做到。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多