私のアプリでは、一連のバックグラウンド タスクを次々に実行する必要があります (タスク : A、B、C など)。これらの各タスクは、異なる Web サービス (XML) と通信します。AFNetworking ライブラリの AFXMLRequestOperation を使用して Web サービスへの要求を開始し、成功ブロックで解析ロジックを処理しています。
次の各タスクは、前のタスクが正常に完了することに依存しています。また、前のタスクが正常に完了してから数秒遅れて、次のタスクが呼び出されるようにします。タスク C が正常に完了したら、完了です。
これはすべてバックグラウンド スレッドで行われているため、UI スレッドは常に反応します (私の UIActivityIndicator はタスクごとに別々に動き続けます)。
擬似コード スニペットは次のとおりです。
-(void)viewDidLoad
{
_operationQueue = [[NSOperationQueue alloc]init];
[_operationQueue setMaxConcurrentOperationCount:1];
[self taskA];
}
- taskA
{
NSMutableURLRequest *request = urlA;
AFXMLRequestOperation *operationA = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
XMLParser.delegate = someClass;
[XMLParser parse];
// Now since the operation is successful, start task B after a delay of 5 seconds
[self performSelector:@selector(taskB) withObject:nil afterDelay:5];
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser) {
NSLog(@"NSError: %@",error);
}];
[_operationQueue addOperation: operationA];
}
- taskB
{
NSMutableURLRequest *request = urlB;
AFXMLRequestOperation *operationB = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
XMLParser.delegate = someOtherClass;
[XMLParser parse];
// Now since the operation is successful, start task C after 10 seconds
[self performSelector:@selector(taskC) withObject:nil afterDelay:10];
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser) {
}];
[_operationQueue addOperation: operationB];
[operationB addDependency:operationA]; // This code seems to produce no result and hence seems redundant
}
- taskC
{
NSMutableURLRequest *request = urlB;
AFXMLRequestOperation *operationC = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
XMLParser.delegate = yetAnotherClass;
[XMLParser parse];
// Now since the operation is successful, mission accomplished!
NSLog(@"Mission accomplished!");
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser) {
}];
[_operationQueue addOperation: operationB];
[operationC addDependency:operationB]; // This code seems to produce no result and hence seems redundant
}
質問:
この実装により、アプリでやりたいことを実現できましたが、NSOperation と NSOperationQueue を正しく使用しているかどうかはわかりません。Apple のドキュメントとチュートリアルから読んだことのうち、NSOperation の強みの 1 つは、異なる操作間の依存関係の確立にそれを使用していることです。ただし、私の例では、タスク A が「正常に」完了した後にのみ operationB が実行されるようにし、NSOperation の「addDependency」機能を活用するにはどうすればよいでしょうか?
また、「taskA」が正常に完了した後、特定の遅延の後にのみ「taskB」が呼び出されるようにしたいと考えています。は
[self performSelector:@selector(taskB) withObject:nil afterDelay:5];
それを行う唯一の方法は?または、NSOperation/NSOperationQueues のいくつかの要素を使用できる別の方法はありますか? それとも、「dispatch_after」のようなものを使用しますか??
全体として、NSOperation を使用して同じタスクを達成するために、コードをより適切に再設計するにはどうすればよいでしょうか?