[XCODE] Objective-Cで並列処理を簡単に実装する方法
今日は、iPhoneアプリでネットワーク処理を行うアプリならきっと有効な、
処理をマルチスレッドで行う方法をブログに書きたいと思います。
ディスパッチキューを用いた実装となります。
1つ目がキューという技術で、キューに処理を登録して、キューは登録された処理を順次実行していくような仕組みを 実現します。
2つ目が、ブロックと呼ばれるObjective-Cの実装技術です。いわゆるクロージャー的なもので、処理を 関数とかメソッドではなく、ブロックという塊で定義できます。
それぞれの技術について、以下の資料が参考になるかもしれません。
並列プログラミングガイド(Apple Document)
スレッドプログラミング(Apple Document)
メインスレッド上でネットワーク処理などの時間のかかる処理を行うと、その間UIが固まってしまい、 使いづらいアプリになってしまいます。
それを防ぐ為に、サーバーと通信を行う処理はメインスレッドから切り離すことで、通信中も UIが固まらないようにしました。
メインスレッドで処理を行うキューと、 メインスレッドではない別のスレッドで処理を行うキューをそれぞれ用意します。
(ViewController.h)
これでキューの定義は完成です。
続いて、キューに処理を登録するところです。 以下の例では、RSSをサーバーから取得するメソッド呼び出しを、サブキューに登録して、 取得した内容を元にUITableViewに反映する処理をメインスレッドで行うように実装しています。
こんな感じで手軽に非同期プログラミングを実装することが出来ます。ありがたい☆
ただ、実装していて感じたのが、状態管理や他スレッドでの実行結果の扱いなど、 色々と難しいなぁと感じる部分も多々ありました。
こーゆうのは、色々と本とか読んで、セオリーを学ぶ必要があるんだなと感じました。
最後までお読み頂きましてありがとうございました(⌒▽⌒)
ディスパッチキューを用いた実装となります。
利用する技術
大きく2つの技術を利用します。1つ目がキューという技術で、キューに処理を登録して、キューは登録された処理を順次実行していくような仕組みを 実現します。
2つ目が、ブロックと呼ばれるObjective-Cの実装技術です。いわゆるクロージャー的なもので、処理を 関数とかメソッドではなく、ブロックという塊で定義できます。
それぞれの技術について、以下の資料が参考になるかもしれません。
並列プログラミングガイド(Apple Document)
スレッドプログラミング(Apple Document)
マルチスレッドの使いどころ
色々な利用用途があると思いますが、 今回はRSSデータをサーバーからダウンロードして、XMLをパースする処理を メインスレッドではない別スレッドで実行するようにしました。メインスレッド上でネットワーク処理などの時間のかかる処理を行うと、その間UIが固まってしまい、 使いづらいアプリになってしまいます。
それを防ぐ為に、サーバーと通信を行う処理はメインスレッドから切り離すことで、通信中も UIが固まらないようにしました。
マルチスレッドの実装方法
まずは、キューを準備します。メインスレッドで処理を行うキューと、 メインスレッドではない別のスレッドで処理を行うキューをそれぞれ用意します。
(ViewController.h)
@interface ViewController : UIViewController { // execute async dispatch_queue_t main_queue; dispatch_queue_t sub_queue; } @end(ViewController.m)
@implementation ViewController - (void)viewDidLoad { [superviewDidLoad]; // メインスレッド用で処理を実行するキューを定義するする main_queue = dispatch_get_main_queue(); // サブスレッドで実行するキューを定義する sub_queue = dispatch_queue_create("net.yoheim.net.iphonestudy.rss", 0); } 〜省略〜 @end
これでキューの定義は完成です。
続いて、キューに処理を登録するところです。 以下の例では、RSSをサーバーから取得するメソッド呼び出しを、サブキューに登録して、 取得した内容を元にUITableViewに反映する処理をメインスレッドで行うように実装しています。
-(void)loadRssAndShowToUI { // サブスレッドで行う処理をブロックで指定します。 dispatch_async(sub_queue, ^{ [self loadRSS:url]; // loadRSSメソッドの実行後に、取得したRSSの内容をtableViewに表示します。 // UIを変更する処理はメインスレッドで行うため、main_queueに処理を登録します。 dispatch_async(main_queue, ^{ [tableView reloadData]; [tableView setNeedsDisplay]; }); }); }
こんな感じで手軽に非同期プログラミングを実装することが出来ます。ありがたい☆
最後に
簡単に非同期処理を実装できる点は、スゴく良いなぁと思いました。ただ、実装していて感じたのが、状態管理や他スレッドでの実行結果の扱いなど、 色々と難しいなぁと感じる部分も多々ありました。
こーゆうのは、色々と本とか読んで、セオリーを学ぶ必要があるんだなと感じました。
最後までお読み頂きましてありがとうございました(⌒▽⌒)