Appel asynchronous Swift 4 avec for loop exécuté dans l'ordre à l'aide de DispatchGroup, DispatchQueue et DispatchSemaphore

Je veux exécuter une boucle for dans swift dans l' ordre , DispatchGroup les lancera set, donc je veux utiliser DispatchQueue et DispatchSemaphore pour atteindre mon objective. Je n'ai pas réussi à faire fonctionner mon programme, comment puis-je les forcer à attendre et courir un par un?

let dispatchGroup = DispatchGroup() let dispatchQueue = DispatchQueue(label: "taskQueue") let dispatchSemaphore = DispatchSemaphore(value: 1) for c in self.categories { dispatchSemaphore.wait() dispatchQueue.async(group: dispatchGroup) { if let id = c.categoryId { dispatchGroup.enter() self.downloadProductsByCategory(categoryId: id) { success, data in if success, let products = data { self.products.append(products) } dispatchSemaphore.signal() dispatchGroup.leave() } } } } dispatchGroup.notify(queue: dispatchQueue) { self.refreshOrderTable { _ in self.productCollectionView.reloadData() NVActivityIndicatorPresenter.sharedInstance.stopAnimating() } } 

Merci à Palle , voici mon code final:

 let dispatchGroup = DispatchGroup() let dispatchQueue = DispatchQueue(label: "taskQueue") let dispatchSemaphore = DispatchSemaphore(value: 0) dispatchQueue.async { for c in self.categories { if let id = c.categoryId { dispatchGroup.enter() self.downloadProductsByCategory(categoryId: id) { success, data in if success, let products = data { self.products.append(products) } dispatchSemaphore.signal() dispatchGroup.leave() } dispatchSemaphore.wait() } } } dispatchGroup.notify(queue: dispatchQueue) { DispatchQueue.main.async { self.refreshOrderTable { _ in self.productCollectionView.reloadData() } } } 

Vous pouvez placer toute la boucle dans un bloc au lieu de placer simplement la fonction de téléchargement dans un bloc:

 dispatchQueue.async { for c in self.categories { if let id = c.categoryId { self.downloadProductsByCategory(categoryId: id) { success, data in if success, let products = data { self.products.append(products) } dispatchSemaphore.signal() } dispatchSemaphore.wait() } } } 

Vous pouvez simplifier votre code en utilisant flatMap pour déballer vos identifiants de produit:

 for id in self.categories.flatMap({$0.categoryId}) { ... }