2016-09-08 4 views
-1

Ich habe eine Blockhohlraumfunktion erstellt, die AFNetworking-Bibliothek verwendet. Diese Funktion wird für GET Anfrage verwendet und verwendet so.iOS Warteblock bis Ende

[Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) { 
    //use response here 
}]; 

Alles funktioniert gut, aber ich wirklich Kopfschmerzen bekommen, wenn ich diesen Block in einer Funktion, die einen Wert, zum Beispiel zurückkommen müssen.

+ (NSArray*)OnlineClients 
{ 
    NSString *clientsUrlStr = [NSString stringWithFormat:@"%@/sinch/clients", ROOT_URL]; 
    __block NSArray *clients = [[NSArray alloc] init]; 
    [Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) { 
     clients = [response componentsSeparatedByString: @","]; 
    }]; 

    return clients; 
} 

OnlineClients Array-Funktion zurückkehrt immer 0 item weil Anforderungsblock nicht mit Abschluss beendet ist.

Also, wie kann ich für Block Abschluss warten Reaktionsanforderung für die Rückkehr in eine Funktion zu bekommen?

Ich habe keine Lösung gefunden verschiedene Themen in Stackoverflow und Google gesucht, aber kann.

Bitte helfen.

+1

Dann haben Sie nicht sehr gut gesucht. Dies ist wahrscheinlich die am häufigsten gestellte und beantwortete Frage in allen iOS-Programmierung auf Stack Overflow. – matt

+0

Mögliche Duplikat [iOS: Warten auf API Completion-Block und der Rückkehr das Ergebnis] (http://stackoverflow.com/questions/23507331/ios-waiting-for-api-completion-block-and-returning-the-result) – HAS

+0

http://stackoverflow.com/a/23507361/1489885 – HAS

Antwort

1

Es gibt mehrere Möglichkeiten, mit dem Problem fertig zu werden. Sie können entweder dispatch_group oder dispatch_semaphore verwenden, um auf die Antwort eines asynchronen Aufrufs vor dem Rückgabewert zu warten, oder Ihre Methode so ändern, dass ein Block die Antwort zurückrufen kann. Bitte schauen Sie sich die Codes unten an. Um bemerkt zu werden, dass dispatch_group und dispatch_semaphore den aktuellen Thread blockieren, um zu warten, bis ein anderer ein Signal auslöst, sollte er es daher nicht auf dem Haupt-Thread verwenden. Meiner Meinung nach würde ich die dritte Lösung vorschlagen. Ich hoffe, es würde dir helfen.

//1 
+ (NSArray*)OnlineClients 
{ 
    dispatch_group_t serviceGroup = dispatch_group_create(); 

    NSString *clientsUrlStr = [NSString stringWithFormat:@"%@/sinch/clients", ROOT_URL]; 
    __block NSArray *clients = [[NSArray alloc] init]; 
    [Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) { 
     clients = [response componentsSeparatedByString: @","]; 
     dispatch_group_leave(serviceGroup); 
    }]; 

    dispatch_group_enter(serviceGroup); 

    return clients; 
} 

//2 
+ (NSArray*)OnlineClients 
{ 
    dispatch_semaphore_t sema = dispatch_semaphore_create(0); 

    NSString *clientsUrlStr = [NSString stringWithFormat:@"%@/sinch/clients", ROOT_URL]; 
    __block NSArray *clients = [[NSArray alloc] init]; 
    [Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) { 
     clients = [response componentsSeparatedByString: @","]; 
     dispatch_semaphore_signal(sema); 
    }]; 

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 

    return clients; 
} 

//3 
+ (void)getOnlineClientsWithCompletionBlock:(void (^) (NSArray *clients))completionBlock 
{ 
    NSString *clientsUrlStr = [NSString stringWithFormat:@"%@/sinch/clients", ROOT_URL]; 
    __block NSArray *clients = [[NSArray alloc] init]; 
    [Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) { 
     clients = [response componentsSeparatedByString: @","]; 
     if (completionBlock) { 
      completionBlock(clients); 
     } 
    }]; 

} 
+0

1 & 2 werden den Thread richtig blockieren, der, wenn auf dem Hauptthread alle UI-Interaktionen blockiert wird. Könnte nützlich sein, das zu erwähnen. – sbarow

+0

@sbarow genau. Vielen Dank für Ihren Punkt, sollte in Bezug auf die Thread-Blockierung vorsichtig sein. – HDT

+0

Zuerst, danke für die Hilfe. Lösung 1: Ich sehe das nicht auf irgendetwas warten, das Array gibt immer noch '0 Elemente' zurück, ehrlich gesagt habe ich das schon einmal versucht, aber es funktioniert nicht. Lösung 2: Wenn ich diesen Code anwende, wie ich es schon einmal getan habe, wartet das auf ewig und kommt nie wieder zurück. – vietnguyen09