2017-08-30 1 views
1

Ich versuche, eine Completion-Handler in einer for-Schleife zu verwenden. Das Problem besteht darin, dass die Schleife weiterhin ausgeführt wird, bevor der Beendigungshandler zurückkehrt, da es sich um einen Async-Aufruf handelt. Beigefügt ist mein Code. Muss ich GCD verwenden? Ich bin neu (offensichtlich) zu swift/ios. Jeder Rat würde sehr geschätzt werden. Bobverschachtelte Completion-Handler analysieren

for srcTerm in sFields { //search using all search fields 

     multiQuery (searchTerm: srcTerm) { 

      if srResult.count < self.lastValue { 
       self.lastValue = srResult.count 
       self.lastSearch = srcTerm 
      } 
     } 
     // Do more stuff 
    } 


    func multiQuery (searchTerm: String, completion: @escaping ([PFObject]) ->()) { 

     var exArray = [PFObject]() 
     let query = PFQuery(className: "searchLinks") 

     do { 

      query.whereKey("searchTerms", equalTo: searchTerm) 

      query.findObjectsInBackground (block: { (objects, error)-> Void in 
       if let error = error { 
        print("Error Generated: ",error) 
        return 
       } 
       if let objects = objects { 
        // do stuff 
       } 
       completion(self.srResult) 
      }) 
     } 
    }    // end of function 
+0

Es Es gibt mehrere Möglichkeiten, dies zu tun (Dispatch Groups, Versprechungen, etc.). Sehen Sie sich https://stackoverflow.com/a/23112134/2124535 an. – nathan

+0

Mögliches Duplikat von [GCD mit verschachtelten Parse-Abfragen] (https://stackoverflow.com/questions/31347407/gcd-with-nested-parse-queries) – nathan

+0

Was möchten Sie tun, nachdem alle Abfragen durchgeführt wurden? Die Frage/Antwort, die oben verlinkt ist (die zweite) scheint das zu sein, wonach Sie suchen, obwohl die API in Swift 3 ein wenig aktualisiert wurde. – nathan

Antwort

2

Sie könnten DispatchGroups verwenden, hier ein Beispiel ist (aus https://medium.com/@wilson.balderrama/how-to-use-dispatchgroup-gdc-with-swift-3-35455b9c27e7 Ähnlich GCD with nested Parse Queries aber aktualisiert Swift 3-API.):

// Just a sample function to simulate async calls 
func run(after seconds: Int, closure: @escaping() -> Void) { 
    let queue = DispatchQueue.global(qos: .background) 
    queue.asyncAfter(deadline: .now() + .seconds(seconds)) { 
     closure() 
    } 
} 

let group = DispatchGroup() 

group.enter() 
run(after: 6) { 
    print("Hello after 6 seconds") 
    group.leave() 
} 

group.enter() 
run(after: 3) { 
    print("Hello after 3 seconds") 
    group.leave() 
} 

group.enter() 
run(after: 1) { 
    print("Hello after 1 second") 
    group.leave() 
} 


group.notify(queue: DispatchQueue.global(qos: .background)) { 
    print("All async calls were run!") 
} 

Arbeiten mit dem Code:

let group = DispatchGroup() 

for srcTerm in sFields { //search using all search fields 
    group.enter() 
    multiQuery (searchTerm: srcTerm) { 
     if srResult.count < self.lastValue { 
      self.lastValue = srResult.count 
      self.lastSearch = srcTerm 
     } 
     group.leave() 
    } 
} 

group.notify(queue: DispatchQueue.global(qos: .background)) { 
    // Do something after all async calls are done 
} 
+0

Danke Nathan! Ich wusste nicht, dass es so einfach ist. Vielen Dank. –

Verwandte Themen