Devo sincronizzare un gruppo di informazioni dal mio RestAPI. Devo fare 6 chiamate RestAPI per completare il lavoro. Ho progettato le chiamate API con Blocks e restituisco NSError se ce n'è. 3 di queste chiamate devono essere eseguite nidificate perché la prima chiamata fornisce informazioni agli altri e consente l'esecuzione mentre le altre 3 chiamate possono essere eseguite indipendentemente. causa di migliorare le prestazioni della rete, ho progettato la mia chiamata di sincronizzazione come segue:NSBlockOperation, NSOperationQueue e Blocks
- 1 NSBlockOperation che contiene i primi 3 blocchi annidati;
- 1 NSBlockOperation che contiene altri tre blocchi;
- 1 NSBlockOperation che uso come "semphore" e mi dice quando tutto il lavoro è finito.
Ultimo NSBlockOperation ha dipendenza dai precedenti due NSBlockOperation.
Ho anche un NSOperationQueue che contiene tutti e tre gli NSBlockOperation in cui il semaforo NSBlockOperation viene aggiunto come ultimo nella coda. Il risultato che dovrei ottenere è: primi due blocchi chiamati simultaneamente e quando il loro lavoro termina, viene chiamato il semaforo NSBlockOperation e restituisce i controlli all'utente che fornisce UIAlertMessage.
Il risultato non è quello spiegato in precedenza: i controlli vengono restituiti senza attendere la fine del blocco syncAllBlocksInformation.
Sotto il codice che contiene 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];
}
E qui, codice che chiama sopra blocco:
-(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];
}
}];
}
Cosa c'è di sbagliato?
Hai provato a rendere 'NSOperationQueue' una variabile di istanza della classe che include? –
L'ho fatto. Ho dichiarato come variabile di istanza e l'ho istanziato in ViewDidLoad. Niente è cambiato. – dpizzuto