Sto cercando di capire i gestori di completamento & blocchi. Credo che tu possa usare i blocchi per molte cose di programmazione profonda senza gestori di completamento, ma penso di capire che i gestori di completamento sono basati su blocchi. (Quindi fondamentalmente gli addetti al completamento hanno bisogno di blocchi ma non viceversa).Come funziona un gestore di completamento su iOS?
così ho visto questo codice su internet circa il vecchio quadro twitter:
[twitterFeed performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (!error) {
self.successLabel.text = @"Tweeted Successfully";
[self playTweetSound];
} else {
// Show alert
}
// Stop indicator
sharedApplication.networkActivityIndicatorVisible = NO;
}];
Qui stiamo chiamando un metodo che fa cose (esegue TWRequest) e ritorna al termine con responseData & urlResponse errore &. Solo quando ritorna esegue il blocco che i test hanno concesso e ferma l'indicatore di attività. PERFEZIONARE!
Ora, questa è una messa a punto che ho per un'altra app che funziona, ma sto cercando di mettere insieme i pezzi:
@interface
Define an ivar
typedef void (^Handler)(NSArray *users);
Declare the method
+(void)fetchUsersWithCompletionHandler:(Handler)handler;
@implementation
+(void)fetchUsersWithCompletionHandler:(Handler)handler {
//...Code to create NSURLRequest omitted...
__block NSArray *usersArray = [[NSArray alloc] init];
//A. Executes the request
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Peform the request
NSURLResponse *response;
NSError *error = nil;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
// Deal with your error
if (error) {
}
NSLog(@"Error %@", error);
return;
}
// Else deal with data
NSString *responseString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
usersArray = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSASCIIStringEncoding] options:0 error:nil];
// Checks for handler & returns usersArray to main thread - but where does handler come from & how does it know to wait tip usersArray is populated?
if (handler){
dispatch_sync(dispatch_get_main_queue(), ^{
handler(usersArray);
});
}
});
}
Qui è la mia comprensione:
- fetchUsersWithCompletionHandler è, ovviamente, l'omologo di performRequestWithHandler
- sfortunatamente questo è un po 'più complesso perché c'è una chiamata GCD nel modo ...
In pratica, la richiesta viene eseguita e l'errore viene gestito, i dati vengono gestiti e quindi il gestore viene controllato. La mia domanda è, come funziona questa parte del gestore? Capisco se esiste, quindi tornerà alla coda principale e restituirà l'array Users. Ma come fa ad aspettare che venga compilato usersArray? Immagino che ciò che mi confonde sia il fatto che il metodo: block in questo caso ha un altro blocco al suo interno, la chiamata dispatch_async. Immagino che quello che sto cercando sia la logica che in realtà fa roba e sa QUANDO restituire la risposta Data e urlResponse. So che non è la stessa app, ma non riesco a vedere il codice per performRequestWithHandler.
2 domande: (1) perché nel passaggio 3 si dice "il tempo passa, finché la coda di sfondo ha alcune risorse gratuite". Perché NON dovrebbe avere risorse gratuite? lo stesso nei passaggi 7/8 con la coda principale. Perché NON dovrebbe avere risorse libere e quindi aspettare? E il più importante, in che modo il gestore "gestisce" l'array Users per inviarlo? Quale parte del codice dice al gestore di inviare i dati a chi lo ha chiamato? – marciokoko
Vedere la mia risposta modificata. – deekay
Qual è la necessità di convertire 'NSData' in' NSString' e poi di nuovo in 'NSData'? – Rishab