libro
www.tuyano.com
初心者のためのObjective-Cプログラミング入門

NSTimerとNSThread (5/6)

作成:2011-03-03 08:55
更新:2011-11-13 22:09

■NSThreadを使ってみる

では、実際にNSThreadを使って複数の処理を並行して動かしてみましょう。NSThreadは、先に説明したように、ターゲットとなるオブジェクトのメソッドを新しいスレッド内で実行させます。ですから、実行するメソッドを持ったクラスを用意しておくことになります。

下のリスト欄に、簡単な利用例を掲載しておきます。MyTestClassクラスを修正してNSThreadを利用する形にしてみました。それをmainから新スレッドで実行させています。同時に複数の処理が動いていることが実感できるよう、2つのスレッドを作成してあります。また、例によってNSRunLoopを使って終了しないようにしてありますので、適当なところで強制終了してください。

MyTestClassクラスの基本部分は、先のNSTimerで使ったときとほぼ同じです。ここでは、printMessage:メソッドを新スレッドで呼び出すようにしてあります。printMessage:では、whileの繰り返しを使って数字をカウントして出力する処理を行い、カウントした数字が終了値まできたら繰り返しを抜けて終わるようにしてあります。

まぁ、やっていることは単純ですが、一つ、見覚えのないメソッドが登場していますね。こういうものです。
[NSThread sleepForTimeInterval:1.0];
このsleepForTimeInterval:というのは、スレッドを「スリープ」させるものです。引数で指定した秒数だけ、スレッドの実行を停止します。まぁ、このサンプルではなくてもいいんですが、そうするとほとんど瞬時に処理が終わってしまうので、「え? 今、本当に並行して複数の処理が動いてたの?」と頭の周りを???がぐるぐる回ることになりかねないため、これでときどき止めながら動かしていたわけです。

こうして用意されたMyTestClassprintMessage:を新しいスレッドから実行させているのが、main関数にあるこの処理です。
[NSThread detachNewThreadSelector:@selector(printMessage:)
        toTarget:obj1 withObject:@"first"];
セレクタには、@selector(printMessage:)というようにしてprintMessage:を指定しています。ターゲットはMyTestClassインスタンスが収められた変数。そしてメソッドの引数にNSStringを用意しています。これで、後は放っておくだけ。勝手に処理を実行していってくれるのです。

※プログラムリストが表示されない場合

AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。

●プログラム・リスト●

※MyTestClass.h

#import <Cocoa/Cocoa.h>

@interface MyTestClass : NSObject {
	int count;
	int endcount;
}

+(MyTestClass*)myTestClassToEndCount:(int)n;
-(void)setEndCount:(int)n;
-(void)printMessage:(NSString*)s;

@end
#import <Foundation/Foundation.h>

@interface MyTestClass : NSObject {
	int count;
	int endcount;
}

+(MyTestClass*)myTestClassToEndCount:(int)n;
-(void)setEndCount:(int)n;
-(void)printMessage:(NSString*)s;

@end


※MyTestClass.m

#import "MyTestClass.h"

@implementation MyTestClass

+(MyTestClass*)myTestClassToEndCount:(int)n {
	MyTestClass* obj = [[MyTestClass alloc] init];
	[obj setEndCount:n];
	return obj;
}
-(void)setEndCount:(int)n {
	endcount = n;
}
-(void)printMessage:(NSString*)s {
	BOOL flg = YES;
	while (flg) {
		[NSThread sleepForTimeInterval:1.0];
		NSLog(@"%@:%i",s,++count);
		if (endcount == count) {
			flg = NO;
			NSLog(@"end...");
		}
	}
}

@end


※main関数のソースコード

#import <Foundation/Foundation.h>
#import "MyTestClass.h"

int main (int argc, const char * argv[]) {
    @autoreleasepool {
        MyTestClass* obj1 = [MyTestClass
                             myTestClassToEndCount:5];
        MyTestClass* obj2 = [MyTestClass
                             myTestClassToEndCount:3];
        [NSThread detachNewThreadSelector:
         @selector(printMessage:)
                                 toTarget:obj1 withObject:@"first"];
        [NSThread detachNewThreadSelector:
         @selector(printMessage:)
                                 toTarget:obj2 withObject:@"second"];
        NSLog(@"start!!");
        
        // 終了しないようにしておく
        [[NSRunLoop currentRunLoop] run];
    }
    return 0;
}

※関連コンテンツ

「初心者のためのObjective-Cプログラミング入門」に戻る