GCDを使って並列非同期通信
GCDの並列非同期通信
GCDの並列非同期処理を行います。
非同期通信
NSURL *url = [NSURL URLWithString:@"http://www.apple.com"]; // UI変更用にmainThreadを準備 dispatch_queue_t main = dispatch_get_main_queue(); // 並列のディスパッチキューを準備 dispatch_queue_t sub = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 並列のディスパッチキューで非同期処理 dispatch_async(sub, ^{ // 並列非同期で通信メソッドの実行 [RequestManager sendAsynchronousRequest:url completionHandler:^(NSURLResponse *response, NSError *connectionError) { if (connectionError) { NSLog(@"nooaonoaaa!1!!!%@",connectionError); } else { dispatch_async(main, ^{ // UIの変更はmainで行う self.textView.text = [NSString stringWithFormat:@"%@",response]; }); } }]; // この処理は処理通信より先に実行される NSLog(@"通信中"); });
通信メソッド
+ (void) sendAsynchronousRequest:(NSURL*) requestURL completionHandler:(void (^)(NSURLResponse* response, NSError* connectionError))handler { // SessionTaskの準備(resume呼ぶまで通信開始はしないので注意) NSURLSessionTask * task = [[NSURLSession sharedSession] dataTaskWithURL:requestURL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // errorがnullだったら通信成功してるので結果を返す if (!error) { handler(response, error); } }]; // 5秒待つ sleep(5); // 通信の開始 [task resume]; }
これを実行すると(通信成功するのを前提)
まず、通信用のメソッドsendAsynchronousRequestが呼ばれ、通信準備が非同期で行われる。
並列非同期なので、sendAsynchronousRequestの次の処理である、Logを出す処理も別スレッドで開始される。
この時sendAsynchronousRequest内のBlocksの式の部分(if else)が実行されたりはしないので注意。なぜなら、Blocksの式の部分の実行はsendAsynchronousRequest内のhandler()によってるから。
通信メソッド側の処理は、SessionTaskを生成し、5秒待つ処理があるので5秒待つ。
この間にLogは出す処理は終わってる。通信処理メソッド側は、5秒待ち終えたら通信の開始。
Blocks部分は同期的に処理されていくのでdataTaskWithURLからcompletionHandlerをが実行されるまで実行されない。
通信が終了しコールバックを得たら、dataTaskWithURLのBlocks内の式の部分が実行される。
sendAsynchronousRequestにコールバックが送られたらsendAsynchronousRequestのBlocksの式の部分が実行される。
メインスレッドからUIの変更を行う。
用意しておいたtextViewに通信結果が表示される。