2011年4月7日木曜日

メインスレッドで実行させるマクロに目からウロコ


Titanium Mobileのモジュールを作っているときに、あるメソッドをメインスレッドで実行する必要があったのですが、Titanium MobileのSDKにマクロが定義されています。

そのマクロが「いいね!」だったのでご紹介。
(すごいベタな手法なのかもしれませんが...)

#define ENSURE_UI_THREAD_1_ARG(x) ¥
if (![NSThread isMainThread]) { ¥
[self performSelectorOnMainThread:_cmd withObject:x waitUntilDone:WAIT_UNTIL_DONE_ON_UI_THREAD modes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; ¥
return; ¥
} ¥

メインスレッド以外から実行された場合、自分自身をメインスレッドで呼び直します。
呼び直された際、[NSThread isMainThread]がTRUEなので、マクロ以降のコードが実行されると。

ちなみに_cmdってのが、実行中のメソッドのセレクタとなる暗黙な変数だそうで(知らなかった...)
詳しくはこちらを参照してください

使い方は、

- (void)hoge:(id)args
{
    ENSURE_UI_THREAD_1_ARG(args);

    // 以降はメインスレッドで実行される
}

他にも、メインスレッドで実行するためのマクロが用意されていますので、
ヘッダを参照してみて下さい。

勉強になった。