シリアルに実行する必要のあるタスクがいくつかありますが、タスクには完了ブロックに次のブロックが含まれています。
これらのタスクを一度に1つずつ実行し、現在のタスクが完了ブロックを完了した後に次のタスクを開始するための優れた手法は何ですか?
シリアルNSOperationQueueを使用するNSOperationサブクラス以外の手法はありますか?
標準ソリューション:
NSOperationQueue
の。maxConcurrentOperationCount
_ 1
あなたはそれをしたくないと言いますが、理由は言いません。シリアル キューは、最も論理的なソリューションです。
例えば:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
[queue addOperationWithBlock:^{
NSLog(@"Starting #1");
sleep(3);
NSLog(@"Finishing #1");
}];
[queue addOperationWithBlock:^{
NSLog(@"Starting #2");
sleep(3);
NSLog(@"Finishing #2");
}];
[queue addOperationWithBlock:^{
NSLog(@"Starting #3");
sleep(3);
NSLog(@"Finishing #3");
}];
serial が必要ない場合はNSOperationQueue
、標準の同時キューを使用できますが、各操作を前の操作に依存させるだけです。シリアル キューを使用せずに、探しているシリアル動作を実現できます。
例えば:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSOperation *operation;
NSOperation *previousOperation;
operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"Starting #1");
sleep(3);
NSLog(@"Finishing #1");
}];
[queue addOperation:operation];
previousOperation = operation;
operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"Starting #2");
sleep(3);
NSLog(@"Finishing #2");
}];
[operation addDependency:previousOperation];
[queue addOperation:operation];
previousOperation = operation;
operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"Starting #3");
sleep(3);
NSLog(@"Finishing #3");
}];
[operation addDependency:previousOperation];
[queue addOperation:operation];
を使用して GCD シリアル キューを作成することもできますdispatch_queue_create
。の代わりに GCD を使用することを除いて、最初のオプションと同じことを実現しますNSOperationQueue
。
例えば:
dispatch_queue_t queue = dispatch_queue_create("com.ConnerDouglass.operationtest", 0);
dispatch_async(queue, ^{
NSLog(@"Starting #1");
sleep(3);
NSLog(@"Finishing #1");
});
dispatch_async(queue, ^{
NSLog(@"Starting #2");
sleep(3);
NSLog(@"Finishing #2");
});
dispatch_async(queue, ^{
NSLog(@"Starting #3");
sleep(3);
NSLog(@"Finishing #3");
});
これは興味深い解決策だと思います: https://github.com/berzniz/Sequencer
このようなものはどうですか:
-(void)start
{
// Start the async chain
[self performSelectorInBackground:@selector(action1) withObject:nil];
}
-(void)notifyDone:(NSNumber *)taskID
{
NSLog(@"Done with task #%i", taskID.intValue);
}
-(void)action1
{
// Do some fancy async stuff here
// Now, we are done. Notify the main thread that task 1 is complete.
[self performSelectorOnMainThread:@selector(nofityDone:) withObject:[NSNumber numberWithInt:1] waitUntilDone:YES];
// Move onto the next task once the main thread is done handling the notification
[self action2];
}
-(void)action2
{
// Do the same sort of thing as "action1" did, then call he next method
}