2010年11月11日木曜日

スレッド

IOS4からiPhoneでもスレッドが使えるようになりました。
スレッド呼び出しは、UIViewの「performSelectorInBackground」メソッドを使用します。

performSelectorInBackground:スレッドのセレクタ withObject:オブジェクト

例えば、ボタンがクリックされたら別スレッドで処理を走らせるには、以下のようにします。

-(IBAction) clickBtnStart:(UIButton*)sender
{
    // ラベルに別スレッドが走ることを表示
    label.text = @"Running background thread";

    // UIActivityIndicatorでwaitアニメーションさせる
    [activityIndicator startAnimating];


    // 別スレッドを呼び出し
    [self performSelectorInBackground:@selector(backgroundThread:) withObject:nil];
}

-(void) backgroundThread:(NSObject*)param
{
    NSAutoreleasePool* pool;
    pool = [[NSAutoreleasePool alloc] init];
   
    [NSThread sleepForTimeInterval:10.0];  // wait 10sec
   
    [activityIndicator stopAnimating];
    label.text = @"Finished";
    [pool release];
}

上の例は、ボタンがクリックされたらラベルに「Running background thread」と表示し、ActivityIndicatorでWaitのアニメーションをさせます。

backgroundThreadが別スレッドで動作する処理です。
「NSAutoreleasePool」というのは、インスタンス確保されたメモリを自動破棄する仕組みです。
NSAutoreleasePoolの生成からreleaseまでの間にインスタンスの確保が行われた場合、releaseでそれまで生成されたインスタンスを一括解放してくれるというものです。
ただ、自動で解放するという仕組みがなかなかくせ者で、思わぬクラスで自動解放されてしまったりすることがあるので注意が必要です。
上記の例ではインスタンス生成を行っていないので無意味ですが、忘れないようにとりあえず書いています。

NSThreadクラスの「sleepForTimeInterval」メソッドで10秒ウェイトさせた後、スレッドの処理が終了したことをラベルとActivityIndicatorのアニメーションをストップさせることで通知させています。

上記のようにすると、バックグランドスレッドで重い処理を行わせていても、メインスレッドにほとんど影響がないことが分かります。

0 件のコメント:

コメントを投稿