Hatena::ブログ(Diary)

fn7の日記

2010-07-12

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

| 01:31 | NSOperationQueueを使ったスレッド処理の簡単な例のブックマークコメント

目的

  • NSOperationQueueを使った処理をする

仕様

ソース

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

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