Thread内ループの停止

ツイッターの @iphone_dev_jp でお問い合わせを受けましたので、久しぶりに技術的なコラム(^^;

iOSでもThreadがサポートされており、マルチスレッドでの処理が可能な事はご存知だと思います。ここではiOS4.0以上でサポートされているGCDでの例を挙げます。

並列して処理をしたい場合、Threadを生成して平行して処理をさせる事は有効だと思います。マルチコアCPUをサポートしたiPad2やiPhone4Sでは特に処理効率が有効になると思います。
それにThreadを使用すると一つの処理をまとめて「ポイッ」と投げてしまう事が出来ますので、開発上も楽チンだと思っています(ただし何でもカンでもThreadにする必要はないですし、余計に面倒くさくなります)。

普通に使われているiOSもanimationで内部的にはThreadが使われているため、「ポイッ」と投げてやれば勝手にanimationを行ってくれます。

しかしThreadの中で持続的にループを指せようとする場合には問題があります。
Threadを生成したObjectをreleaseしてもそのThreadは自動的に停止してくれる訳ではないのです。

当然僕も「何かThreadを停止させるAPIは無いのか?」と思いました。で、探したのですが見つかりません。もしかしたら僕の探し方が悪いのかもしれませんが、少なくとも僕にはそういうAPIが見つかりませんでした。

そこで…


@interface TimerView : UIView {
    BOOL started;
}
-(void)startTimer;
-(void)stopTimer;
@end

 


@implementation TimerView
-(void)startTimer {
    if(started == NO) {
        started = YES;
        dispatch_queue_t queue;
        queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
        dispatch_async(queue, ^{
            while(started) {
                useconds_t useconds = 5000;
                usleep(useconds);
                スレッドの中でやらせたい事
                if(CONDITION) {
                dispatch_async(dispatch_get_main_queue(), ^ {
                    描画等の処理をする
                });
            }
        }); 
    }
}

-(void)stopTimer {
    started = NO;
}

@end

 

上のソースでは単純にThread内でループを作り、StopTimerメソッドでstartedNOにしてやるだけです。
5000 ミリ秒ごとに起き上がってくる処理の中でチェックし、終了してしまいます。
Threadの中ではしてはイケナイ事が幾つかあります。例えば描画処理等もそれです。それらは


                dispatch_async(dispatch_get_main_queue(), ^ {
                    描画等の処理をする
                });

の中で行います。

Leave a Reply

Your email address will not be published. Required fields are marked *

*

CAPTCHA


WP-SpamFree by Pole Position Marketing