2016-04-18 3 views
1

ich mehrere Anfragen haben:Wie mehrere Alamofire synchronisieren fordert

var data1: MyData? 
var data2: MyData? 
var data3: MyData? 

func makeRequest(url: String, completion: (result: ResponseResult, data: MyData?) -> Void){ 
    Alamofire.request(.GET, url).responseJSON { response in 
     switch response.result { 
     case .Success(let JSON): 
     completion(result: .Success, MyData(JSON)) 
     case. Failure(let error): 
     completion(result: .Failure, nil) 
     } 
    } 
} 

makeRequest(url1){ result, data in 
    data1 = data 
} 
makeRequest(url2){ result, data in 
    data2 = data 
} 
makeRequest(url3){ result, data in 
    data3 = data 
} 

Und nachdem alle Daten i muss die folgende Funktion aufrufen, empfangen wurde: in

workWithData(data1, data2: data2, data3: data3) 

Wie man Barriere für diese drei Anträge diese Situation?

+0

Nach erfolgreichem Aufruf der 3. Anfrage rufen Sie Ihre Funktion auf. –

+0

@AshishKakkad Alamofire-Anfragen sind asynchron –

+0

Verwenden Sie reaktiven Kakao oder etwas ähnliches? Wenn dies der Fall ist, können Sie einen Anruf in ein Signal umwandeln und dann nacheinander anrufen (oder was auch immer Sie wollen). – KlimczakM

Antwort

6

Sie haben DispatchGroup zu verwenden, und vergessen Sie nicht, über Deadlocks.

var data1: MyData? 
var data2: MyData? 
var data3: MyData? 

func makeRequest(url: String, completion: (result: ResponseResult, data: MyData?) -> Void){ 
    Alamofire.request(.GET, url).responseJSON { response in 
     switch response.result { 
     case .Success(let JSON): 
      completion(result: .Success, MyData(JSON)) 
     case. Failure(let error): 
      completion(result: .Failure, nil) 
     } 
    } 
} 

let downloadGroup = DispatchGroup() 

downloadGroup.enter() 
downloadGroup.enter() 
downloadGroup.enter() 

makeRequest(url1){ result, data in 
    data1 = data 
    downloadGroup.leave() 
} 
makeRequest(url2){ result, data in 
    data2 = data 
    downloadGroup.leave() 
} 
makeRequest(url3){ result, data in 
    data3 = data 
    downloadGroup.leave() 
} 

DispatchQueue.global(qos: .background).async { 
    downloadGroup.wait() 
    DispatchQueue.main.async { 
     workWithData(data1, data2: data2, data3: data3) 
    } 
} 
1

Semaphore sollte für Sie arbeiten. Bedenken Sie:

var data1: NSData? 
var data2: NSData? 
var data3: NSData? 

func makeRequest(url: String, completion: (data: NSData?) -> Void){ 

    let request = Alamofire.request(.GET, "https://google.com").responseJSON(queue: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { closureResponse in 

     completion(data: NSData()) 
    } 
} 

let sem = dispatch_semaphore_create(0) 

makeRequest("1"){ data in 
    data1 = data 
    dispatch_semaphore_signal(sem) 
} 
makeRequest("2"){ data in 
    data2 = data 
    dispatch_semaphore_signal(sem) 
} 
makeRequest("2"){ data in 
    data3 = data 
    dispatch_semaphore_signal(sem) 
} 

dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER) 
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER) 
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER) 

print("123") 

Per @James Kommentar, ich habe einige Zeit damit verbracht mit Alamofire spielen. Was ich herausgefunden habe ist, dass es standardmäßig Callbacks in der Hauptwarteschlange liefert. Das ist aus meiner Sicht nicht gut, ich bevorzuge die Hauptfadenbelastung zu minimieren. Ich würde empfehlen, die gleichzeitige Warteschlange für die Rückrufzustellung zu verwenden.

0

Ich denke, Sie sollten, ob Sie es zu Ende Alamofire.request fortzusetzen:

func makeRequest(url: String, completion: (result: ResponseResult, data: MyData?) -> Void){ 
    Alamofire.request(.GET, url).responseJSON { response in 
     switch response.result { 
     case .Success(let JSON): 
      completion(result: .Success, MyData(JSON)) 
     case. Failure(let error): 
      completion(result: .Failure, nil) 
     } 

     if data1 != nil && data2 != nil && data3 != nil { 
      workWithData(data1, data2: data2, data3: data3) 
     } 
    } 
} 
+0

Wenn Alamofire die gleichzeitige Warteschlange unter der Haube für die Rückrufe verwendet, kann dies eine mögliche Ursache für die Race Condition sein. Ich würde empfehlen, dies herauszufinden, und wenn meine Annahme richtig ist, dann * wenn Check * sollte unter Synchronisation Grundelement (lock, dispatch_sync oder was auch immer Sie wollen sonst). –

+0

Könnten Sie das näher erläutern? Was genau ist das Rennen? Welches auch immer das letzte 'data123' ist, das gesetzt wird, wird das' if' eingeben und die anderen nicht. Aufrufe von 'completion' innerhalb von' .responseJSON' sind nicht asynchron, also werden sie abgeschlossen, bevor der switch-case beendet wird. – BallpointBen