问题描述
我们有一个通用的 Requesthandler.swift 文件来处理 get、post http 方法。我们正在整个应用程序中使用此文件来进行 http 请求。 当我们初始化 URLSession 时,delegateQueue 的值应该是多少。
let session = URLSession(configuration: config,delegate: self,delegateQueue:OperationQueue.main)
解决方法
关键的考虑是队列应该是串行队列。正如the docs所说:
队列应该是一个串行队列,以确保回调的正确顺序。
因此,如果您实例化自己的 OperationQueue
,请确保将其 maxConcurrentOperationCount
设置为 1
。
文档继续说:
如果[委托队列是] nil
,会话会创建一个串行操作队列,用于执行所有委托方法调用和完成处理程序调用。
因此,我们通常会将其保留为 nil
,让 URLSession
为我们处理。
不过,通常不会使用 main
队列。这在很大程度上是一个约定问题(如 URLSession.shared
,如果我们不需要委托方法或自定义行为,我们通常使用它,使用串行后台队列)。这种使用串行后台队列的做法是可取的,因为您可以降低委托方法或完成处理程序中的某些缓慢解析操作(或其他操作)影响主线程响应的风险。话虽如此,每当使用串行后台队列时,请确保将 UI 更新(等)分派回主队列。
如果您在整个应用程序中为所有 http 使用它,这是正确的做法。但是,我建议不要创建您自己的会话。已经有一些确切的东西,那就是 URLSession.shared
,尽管文档中讨论了(只有几个)限制。
如果您可以忍受巨大的限制 - 使用共享会话;否则,按照 Rob 的建议使用 nil
,或者如果您 DIY 队列,那么您不想想使用 main 作为您的委托队列。你肯定想要一个后台队列。如果您自己动手做,那么您可能会创建一个单例队列并将其用于所有请求,并根据喜好对其进行配置(并使其连续 - 请参阅 Rob 的回答)。
最后,由于delegate会在delegate queue上调用completion,也就是NOT main,所以每当你需要更新UI的时候就应该在completion里切换到main,所以可能会有一个很多切换到主那里。这并没有错,也没有告诉您使用 main 作为队列。