Ho saputo, questa è una vecchia domanda, ma abbastanza interessante, e c'è una bella soluzione:
Supponiamo che tutte quelle funzioni fossero asincrone. Il modello asincrono è chiamato "Continuazione".
Una possibile implementazione di tale "continuazione" potrebbe utilizzare direttamente le code e i blocchi di invio, ad esempio:
dispatch(my_queue, ^{
[self connectDeviceWithCompletion:^(id result){
if (result) {
[self authenticateWithCompletion:^(id result){
if (result) {
[self performTwoFactorAuthWithCompletion:^(id result) {
if (result) {
...
}
}];
}
}];
}
}];
});
Come puoi vedere, la "continuazione" con la spedizione e i blocchi si confonde rapidamente e non ho nemmeno aggiunto il controllo degli errori e la cancellazione.
Nota che cancellare un blocco che è stato messo in coda non è così facilmente possibile.
Una soluzione più comprensibile che supporti anche la gestione degli errori e la cancellazione può essere ottenuta utilizzando un concetto chiamato "Promise" (vedi wiki Futures e promesse ]. Le promesse sono molto popolari in JavaScript e in altre lingue, ma ci sono alcune librerie Objective-C che implementano Promises, vedi questa risposta:
successo: / fallimento: blocchi vs completamento: blocco .
Utilizzando la RXPromise libreria si potrebbe scrivere:
RXPromise* finalResult = [self connectDevice]
.then(^(id result){
// device successfully connected with result
return [self authenticate];
}, nil)
.then(^id(id result){
// authenticated successfully with result
return [self performTwoFactorAuth];
}, nil)
.then(^id(id result){
// successfully performed two-factor-authentication
// do something
...
}, nil)
[finalResult setTimeout:5*60]; // we cancel everything after 5 minutes
// Catch any error:
finalResult.then(nil, id(NSError* error){
NSLog(@"Something went wrong, or user cancelled with error: %@", error);
});
self.finalResultPromise = finalResult;
...
In seguito:
Supponiamo che l'utente aspetti che un risultato si verifichi alla fine. Quando si ritorna indietro dalla vista corrente, ciò annulla tutte le operazioni asincrone:
- (void) viewDidDisappear:(BOOL)animated {
// we are no longer interested in the result
[self.finalResultPromise cancel];
self.finalResultPromise = nil;
[super viewDidDisappear:animated];
}
Divulgazione: sono l'autore di RXPromsie;)