
【Objective-C】非同期処理を同期的に処理する方法【Xcode10.1】
こういう人に向けて発信しています。
・そもそも「非同期処理」「同期処理」について理解していない人
・「非同期処理」→「同期処理」の書き方を知りたい人
・「非同期処理」について勉強したい人
補足
前回「同期的処理」→「非同期処理」に変更する書き方について
触れてますので、先にそちらをご一読される事をお勧めします。
noteのマガジンで「Objective-C」を用意しております。
Objective-Cでの活用シーンについて
処理A、処理Bとあった時に
処理Aを行った後に処理Bを処理したい
という場合などにご活用ください。
私の実例としてあったのが、
API通信A/API通信Bが両方とも非同期通信しておりました。
しかし、API通信BではAPI通信Aの後に行う必要があり、
API通信Aの処理終了を待つ必要がありました。
そこでAPI通信Aを同期的な処理に変更し、
API通信Bは非同期的な通信のままで成功しました。
Code:Objective-C
下記コードで「//追加」とコメント追加してあるものが、
「非同期処理」を「同期処理」に書き換える為に必要なコードです。
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"検証用:処理start");
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); //追加
/*
disptach_get_global_queueで非同期スレッドのキューを取得し、
dispatch_asyncでそこに処理を追加します。
*/
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
/*
下記for構文に関しては本来は同期処理。
*/
for (int i = 0; i < 3; i++) {
sleep(1);
NSLog(@"検証用:for構文終了");
}
dispatch_semaphore_signal(semaphore); //追加
});
NSLog(@"検証用:wait...");//追加
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//追加
NSLog(@"検証用:finish...");//追加
}
@end
参考
実際に僕が使ったコード
処理の内容を実際にイメージを持来ちやすいように実装したコード、
描いてみますね。
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
[self.collectionView reloadData]; //行いたい処理
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);