RestAPI から大量の情報を同期する必要があります。作業を完了するには、RestAPI 呼び出しを 6 回行う必要があります。ブロックを使用して API 呼び出しを設計し、存在する場合は NSError を返します。これらの呼び出しのうち 3 つをネストして実行する必要があります。これは、最初の呼び出しが他のユーザーに情報を提供し、他の 3 つの呼び出しが独立して実行できる間に実行を許可するためです。ネットワークのパフォーマンスを向上させるために、同期呼び出しを次のように設計しました。
- 最初のネストされた 3 つのブロックを含む 1 つの NSBlockOperation。
- 他の 3 つのブロックを含む 1 つの NSBlockOperation。
- 「セフォア」として使用する 1 つの NSBlockOperation で、すべての作業が完了したときに通知されます。
最後の NSBlockOperation は、前の 2 つの NSBlockOperation に依存しています。
また、セマフォ NSBlockOperation がキューの最後に追加される 3 つの NSBlockOperation すべてを含む NSOperationQueue もあります。私が達成したい結果は次のとおりです。最初の 2 つのブロックが Concurrently と呼ばれ、それらの作業が終了すると、セマフォ NSBlockOperation が呼び出され、UIAlertMessage を提供するユーザーにコントロールが返されます。
その結果は、以前に説明したものとは異なります。コントロールは、syncAllBlocksInformationブロックの終了を待たずに返されます。
NSBlockOperation を含むコードの下:
-(void)syncAllBlocksInformation:(void(^)(NSError *error))completion{
__block NSError *blockError = nil;
NSOperation *syncUserInfoOperation = [NSBlockOperation blockOperationWithBlock:^{
[dataSync syncUserInfo:tfMail.text password:tfPassword.text completion:^(NSError *error, NSNumber *idUser) {
if(!error){
[dataSync syncUserfilesInfo:idUser completion:^(NSError *error) {
if(!error){
[dataSync syncUserBookings:^(NSError *error) {
if(error){
blockError = error;
}
}];
}
else{
blockError = error;
}
}];
}
else{
blockError = error;
}
}];
}];
NSBlockOperation *otherSyncOperations = [NSBlockOperation blockOperationWithBlock:^{
[dataSync syncNewsInfo:^(NSError *error) {
if(error){
blockError = error;
NSLog(@"error %@",error);
}
}];
}];
[otherSyncOperations addExecutionBlock:^{
[dataSync syncLocationsInfo:^(NSError *error) {
if(error){
blockError = error;
NSLog(@"error %@",error);
}
}];
}];
[otherSyncOperations addExecutionBlock:^{
[dataSync syncExoticAnimalTypesAndAnimals:^(NSError *error) {
if(error){
blockError = error;
NSLog(@"error %@",error);
}
}];
}];
NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"END");
}];
[completionOperation setCompletionBlock:^{
NSLog(@"Syc isEx %i",syncUserInfoOperation.isExecuting);
NSLog(@"other isEx %i",otherSyncOperations.isExecuting);
completion(blockError);
}];
NSOperationQueue *opQueue = [NSOperationQueue new];
[completionOperation addDependency:syncUserInfoOperation];
[completionOperation addDependency:otherSyncOperations];
[opQueue addOperation:syncUserInfoOperation];
[opQueue addOperation:otherSyncOperations];
[opQueue addOperation:completionOperation];
}
そして、ここで、上記のブロックを呼び出すコード:
-(IBAction)login:(id)sender{
[self dismissKeyboardOpened:nil];
hud=[MBProgressHUD showHUDAddedTo:self.view animated:YES];
[hud setLabelText:NSLocalizedString(@"login_hud_message", login_hud_message )];
[hud setMode:MBProgressHUDModeIndeterminate];
[self showHudAndNetworkActivity:YES];
[self syncAllBlocksInformation:^(NSError *error) {
[self showHudAndNetworkActivity:NO];
if(!error){
NSLog(@"End LOGIN");
[self showAlert:@"Login" message:@"Login OK" dismiss:YES];
}
else{
[self showAlert:@"Error" message:@"Login NO" dismiss:NO];
}
}];
}
どうしたの ?