Chcę owinąć API asynchronicznej, który wygląda tak:jak owinąć asynchronicznej metody, która przyjmuje blok i skręcić go synchronicznych w Objective C
[someObject completeTaskWithCompletionHandler:^(NSString *result) {
}];
w sposób synchroniczny, że mogę zadzwonić tak
NSString *result = [someObject completeTaskSynchronously];
Jak to zrobić? Zrobiłem trochę czytania doc i wyszukiwarka Google, a próba użycia „dispatch_semaphore” zrobić próbują osiągnąć to tak:
-(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;
}
Ale to nie robi wydaje się działać, to w zasadzie tylko zatrzymać przy dispatch_semaphore_wait. Wykonanie nigdy nie dociera do wewnętrznego bloku, który wykonuje sygnał. Ktoś ma przykład kodu, jak to zrobić? Podejrzewam, że blok musi być na innym wątku, innym niż główny wątek? Załóżmy też, że nie mam dostępu do kodu źródłowego za metodą asynchroniczną. Dzięki!
Jeśli handler ukończenie jest wykonywany w tym samym wątku, który wywołuje dispatch_semaphore_wait ty rzeczywiście impasie wątek ponieważ blok Zakończenie nie mogą być wykonywane aż do wyjścia gwintu z czekania. Czy próbujesz to zrobić w głównym wątku? Lepiej nie blokować głównego wątku przez długi czas, ponieważ musi on stale wysyłać wiadomości. – yurish
Jeśli, jak podejrzewa @urish, obsługa została umieszczona w kolejce do głównego wątku wysyłki, nie możesz czekać. Musisz skonstruować swój przepływ kodu jako maszynę stanu i zrobić wszystko, co trzeba, z wynikiem w procedurze uzupełniania. –
Nie ma ogólnego sposobu, aby to zrobić. Jak powiedzieli inni, jeśli jakaś część asynchronicznego zadania działa poprzez umieszczanie zdarzeń w pętli uruchamiania, zawsze będziesz zaklinowany. Co tak naprawdę * starasz się osiągnąć? Może istnieje inny sposób na uporządkowanie kodu. – JeremyP