使用DispatchGroup,DispatchQueue和DispatchSemaphore按顺序执行带有for循环的Swift 4异步调用

永恒的

我想按顺序快速运行for循环,DispatchGroup会将它们一起触发,因此我想使用DispatchQueue和DispatchSemaphore达到我的目标。我无法使程序正常运行,如何强迫他们等待并逐一运行?

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()
    }
}

感谢Palle,这是我的最终代码:

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()
        }
    }
}

您可以将整个循环放在一个块中,而不仅仅是将下载功能放在一个块中:

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()
        }
    }
}

您可以使用compactMap解开产品ID来简化代码:

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章