Voglio avvolgere un'API asincrona che assomigliano a questo:Come avvolgere un metodo asincrono che prende un blocco e ruotarla sincrono c obiettivo
[someObject completeTaskWithCompletionHandler:^(NSString *result) {
}];
in un metodo sincrono che posso chiamare in questo modo
NSString *result = [someObject completeTaskSynchronously];
Come posso fare questo? Ho fatto qualche lettura doc e Google Search, e tentativo di utilizzare "dispatch_semaphore" fare cercano di raggiungere in questo modo:
-(NSString *) completeTaskSynchronously {
__block NSString *returnResult;
self.semaphore = dispatch_semaphore_create(0);
[self completeTaskWithCompletionHandler:^(NSString *result) {
resultResult = result;
dispatch_semaphore_signal(self.semaphore);
}];
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
return resultResult;
}
Ma questo doesnt sembrano funzionare, è fondamentalmente solo fermare al dispatch_semaphore_wait. L'esecuzione non raggiunge mai il blocco interno che fa il segno. Qualcuno ha un esempio di codice su come farlo? Sospetto che il blocco debba essere su un thread diverso rispetto al thread principale? Inoltre, supponiamo di non avere accesso al codice sorgente dietro il metodo asincrono. Grazie!
Se gestore di completamento viene eseguita sullo stesso thread che chiama dispatch_semaphore_wait si in effetti un punto morto il filo perché il blocco di completamento non può essere eseguito fino a quando il thread da l'attesa. Stai cercando di farlo sul thread principale? È meglio non bloccare il thread principale per molto tempo perché deve inviare messaggi in modo costante. – yurish
Se, come sospettato da @yurish, il gestore è stato accodato al thread di invio principale, non devi aspettare. Devi costruire il tuo flusso di codice come una macchina di stato e fare tutto ciò che deve essere fatto con risultato nel gestore di completamento. –
Non c'è un modo generale per farlo. Come altri hanno già detto, se una parte dell'attività asincrona funziona mettendo eventi nel ciclo di esecuzione, si verificherà sempre un deadlock. Cosa stai cercando di ottenere? Forse c'è un altro modo per strutturare il tuo codice. – JeremyP