これは本当に良い質問です。あなたのアプローチは完全に有効です。ただし、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
println("Parsing JSON on thread: \(NSThread.currentThread()) is main thread: \(NSThread.isMainThread())")
println(JSON)
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
print("Parsing JSON on thread: \(NSThread.currentThread()) is main thread: \(NSThread.isMainThread())")
print(response.result.value)
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
print("Parsing JSON on thread: \(Thread.current) is main thread: \(Thread.isMainThread)")
print(response.result.value)
DispatchQueue.main.async {
print("Am I back on the main thread: \(Thread.isMainThread)")
}
}
)
Alamofireディスパッチキューの内訳
このアプローチに関連するさまざまなディスパッチキューの内訳は次のとおりです。
- NSURLSessionディスパッチキュー
- 検証およびシリアライザー処理のためのTaskDelegateディスパッチキュー
- JSON処理用のカスタムマネージャー同時ディスパッチキュー
- ユーザーインターフェイスを更新するためのメインディスパッチキュー(必要な場合)
概要
メインディスパッチキューに戻る最初のホップを排除することで、潜在的なボトルネックを排除し、リクエスト全体と処理を非同期にしました。驚くばかり!
そうは言っても、Alamofireが実際にどのように機能するかについての内部に精通することがどれほど重要であるかを十分に強調することはできません。自分のコードを改善するのに本当に役立つ何かをいつ見つけることができるかはわかりません。
response
メソッドの2番目のパラメーターresponseSerializer
がserializer
(Alamofire 3.0では)ではなく呼び出されるようになりました。それCannot call value of non-function type 'NSHTTPURLResponse?'
は私を少し混乱させたエラーを引き起こしました。