这是一个非常好的问题。你的方法是完全有效的。但是,Alamofire 实际上可以帮助您进一步简化这一过程。
您的示例代码调度队列分解
在您的示例代码中,您在以下调度队列之间跳转:
- NSURLSession 调度队列
- 用于验证和序列化程序处理的 TaskDelegate 调度队列
- 用于调用完成处理程序的主调度队列
- JSON 处理的高优先级队列
- 用于更新用户界面的主调度队列(如有必要)
如您所见,您到处乱窜。让我们看一下利用 Alamofire 中强大功能的另一种方法。
Alamofire 响应调度队列
Alamofire 在其自身的低级处理中内置了一种最佳方法。最终被所有自定义响应序列化程序调用的单个 response 方法支持自定义调度队列(如果您选择使用它)。
虽然 GCD 擅长在调度队列之间跳转,但您希望避免跳转到繁忙的队列(例如主线程)。通过在异步处理过程中消除跳转回主线程,您可以显着加快处理速度。以下示例演示了如何使用开箱即用的 Alamofire 逻辑来执行此操作。
Alamofire 1.x
let queue = dispatch_queue_create("com.cnoon.manager-response-queue", DISPATCH_QUEUE_CONCURRENT)
let request = Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
request.response(
queue: queue,
serializer: Request.JSONResponseSerializer(options: .AllowFragments),
completionHandler: { _, _, JSON, _ in
// You are now running on the concurrent `queue` you created earlier.
println("Parsing JSON on thread: \(NSThread.currentThread()) is main thread: \(NSThread.isMainThread())")
// Validate your JSON response and convert into model objects if necessary
println(JSON)
// To update anything on the main thread, just jump back on like so.
dispatch_async(dispatch_get_main_queue()) {
println("Am I back on the main thread: \(NSThread.isMainThread())")
}
}
)
Alamofire 3.x(Swift 2.2 和 2.3)
let queue = dispatch_queue_create("com.cnoon.manager-response-queue", DISPATCH_QUEUE_CONCURRENT)
let request = Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
request.response(
queue: queue,
responseSerializer: Request.JSONResponseSerializer(options: .AllowFragments),
completionHandler: { response in
// You are now running on the concurrent `queue` you created earlier.
print("Parsing JSON on thread: \(NSThread.currentThread()) is main thread: \(NSThread.isMainThread())")
// Validate your JSON response and convert into model objects if necessary
print(response.result.value)
// To update anything on the main thread, just jump back on like so.
dispatch_async(dispatch_get_main_queue()) {
print("Am I back on the main thread: \(NSThread.isMainThread())")
}
}
)
Alamofire 4.x (Swift 3)
let queue = DispatchQueue(label: "com.cnoon.response-queue", qos: .utility, attributes: [.concurrent])
Alamofire.request("http://httpbin.org/get", parameters: ["foo": "bar"])
.response(
queue: queue,
responseSerializer: DataRequest.jsonResponseSerializer(),
completionHandler: { response in
// You are now running on the concurrent `queue` you created earlier.
print("Parsing JSON on thread: \(Thread.current) is main thread: \(Thread.isMainThread)")
// Validate your JSON response and convert into model objects if necessary
print(response.result.value)
// To update anything on the main thread, just jump back on like so.
DispatchQueue.main.async {
print("Am I back on the main thread: \(Thread.isMainThread)")
}
}
)
Alamofire 调度队列细分
这里是这种方法所涉及的不同调度队列的细分。
- NSURLSession 调度队列
- 用于验证和序列化程序处理的 TaskDelegate 调度队列
- 用于 JSON 处理的自定义管理器并发调度队列
- 用于更新用户界面的主调度队列(如有必要)
总结
通过消除返回主调度队列的第一跳,您消除了潜在的瓶颈,并使整个请求和处理异步。太棒了!
话虽如此,我不能再强调熟悉 Alamofire 的内部工作原理的重要性了。你永远不知道什么时候能找到真正能帮助你改进自己代码的东西。