4

アプリケーションをシングルスレッドからマルチスレッドに転送するときに、ObjCマルチスレッドの実装が適切であることを確認しようとしています。

現在、シングルスレッド環境ですべてが正しく機能することを確認するために単体テストを設定しています。

これがマルチスレッドで確実に機能するようにするにはどうすればよいですか?引き続き単体テストを使用したいのですが、単体テストでマルチスレッドをテストする方法がわかりません。

明確化:NSBlockOperation/NSOperationQueueを使用してマルチスレッドを実装しています。

4

2 に答える 2

3

このようなものをテストするNSOperationQueueには、テストで制御する必要があります。

テストしているクラスが と呼ばれているとしMySubjectます。NSOperationQueue最初に、テスト用に置き換えて使用できる -- を挿入できるように、リファクタリングする必要があります。したがって、すべての出現を取り除き、[NSOperationQueue mainQueue]それらをクラス変数に置き換えます。MySubjectのコンストラクターのパラメーターからそのクラス変数を初期化します。MySubjectその結果、 のすべてのインスタンス化を passに変更する必要があります[NSOperationQueue mainQueue]

@interface MySubject: NSObject {
  NSOperationQueue* operationQueue;
}
@end

@implementation MySubject
-(MySubject*)initWithOperationQueue:(NSOperationQueue*)queue {
  if ( self = [super init] ) {
    self.operationQueue = [queue retain];
  }
  return self;
}

-(void)dealloc {
  [operationQueue release];
}

-(void)startOperations {
  [operationQueue addOperation:...];
  [operationQueue addOperation:...];
}
@end

クライアントは次のようになります。

subject = [[MySubject alloc] initWithOperationQueue:[NSOperationQueue mainQueue]];
[subject startOperations];

テストのために、テスト用の単純なキューを作成できます...サブジェクトで使用されるメソッドを実装する必要があります。

@interface MyTestOperationQueue: NSMutableArray {
}
@end

@implementation MySubject

-(void)addOperation:(NSOperation*)operation {
  [self addObject:operation];
}
@end

これで、テストは次のようになります。

testQueue = [[MyTestOperationQueue alloc] init];
subject = [[MySubject alloc] initWithOperationQueue:testQueue];
[subject startOperations];

// You may want to have other tests that execute the queue operations
// in a different order
[[testQueue objectAtIndex:0] start];
[[testQueue objectAtIndex:0] waitUntilFinished];
[[testQueue objectAtIndex:1] start];
[[testQueue objectAtIndex:1] waitUntilFinished];

// Verify results

もちろん、この種のテストでは、並行操作が安全に同時に実行できるかどうかを検証することはできませんが、クラスを設計しようとするときに関心のある多くのケースをカバーできます。

于 2011-07-28T00:26:29.887 に答える