NSOperationQueueを使ったスレッド処理の簡単な例

目的

  • NSOperationQueueを使った処理をする

仕様

  • 全10スレッド生成する
  • 3スレッドずつ動く
  • スレッドが完了する前にプロセスが終了しないようにする

ソース

#import <Cocoa/Cocoa.h>

@interface TTOperation : NSOperation
{
  int number;
}
@property int number;
@end

@implementation TTOperation
@synthesize number;
- (id)init{
  if (self = [super init]) {
    self.number = 0;
  }
  return self;
}
- (void)main {
  // スレッドで実行したい処理をここに書く
  [NSThread sleepForTimeInterval: 1.0f];
  NSLog(@"test %d\n", number);
}

- (void)dealloc {
  [super dealloc];
}
@end

int main(int argc, char **argv) {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  // 3スレッドずつ動かす
  queue.maxConcurrentOperationCount = 3;
  TTOperation *operation;
  int i;
  for (i = 0;i < 10; i++) {
    operation = [[TTOperation alloc] init];
    operation.number = i;
    [queue addOperation: operation];
    [operation release];
  }
  // 全てのスレッドが終了するのを待つ
  [queue waitUntilAllOperationsAreFinished];
  [queue release];
  [pool release];
}

iPhoneアプリなら終了アクションしない限りプロセスが生きつづけるが、コマンドラインだとプロセスがすぐ終了してしまう為、何も表示されない。これを防ぐために waitUntilAllOperationAreFinished を呼んでおく。

[参考]


[追記]
isConcurrent で YESを返すようにした場合、NSOperationのサブクラスの main メソッド内のスリープ処理がメインスレッド対象になってしまうのでスレッド処理の効果が見えにくい。

あと、 NSURLConnection を使うときには isConcurrent を YES で返すほうがいいらしい。実験してみよっと。

iPhoneアプリ等では、終了時イベント等で動作しているスレッドにキャンセルを適切に送るのが良いんだろうなぁ。

スレッドについてはもうちょっと勉強しなきゃいけんですな。