2017-08-30 147 views
1

我想在for循環中使用完成處理程序。問題在於它會在完成處理程序返回之前繼續運行循環,因爲它是異步調用。附件是我的代碼。我需要使用GCD嗎?我很新(很明顯)是swift/ios。任何意見將不勝感激。鮑勃解析嵌套完成處理程序

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

有有幾種方法可以做到這一點(派遣組織,承諾等)。看看在https://stackoverflow.com/a/23112134/2124535 – nathan

+0

可能重複[GCD與嵌套解析查詢](https://stackoverflow.com/questions/31347407/gcd-with-nested-parse-queries ) – nathan

+0

在完成所有查詢後你想做什麼?上面提到的問題/響應(第二個)似乎就像你在找什麼,儘管API已經在Swift 3中更新了一點。 – nathan

回答

2

你可以使用DispatchGroups,這裏是一個例子(摘自https://medium.com/@wilson.balderrama/how-to-use-dispatchgroup-gdc-with-swift-3-35455b9c27e7類似GCD with nested Parse Queries但更新斯威夫特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!") 
} 

使用代碼:

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

謝謝納森!我沒有意識到這一點。謝謝。 –