Swift:在任务完成之前调用DispatchGroup notify

时间:2020-02-15 23:58:00

标签: swift multithreading

为什么在库存循环之前调用dispatchGroup.notify?不应该在任务完成后才调用它吗?下面是我的控制台的图像,向您展示我的意思。

override func viewDidLoad() {
    super.viewDidLoad()

     fetch { (stocks) in
        self.hud.dismiss()

          APIManager.shareInstance.getStockList(for: self.fetchedStocks) { (result) in

            switch result {
            case .success(let stocks):
                DispatchQueue.main.async {
                    self.fetchedStocks = stocks
                    print(self.fetchedStocks)
                }

            case .failure(let error):
                print("Couldn't find Symbol")
                print(error.localizedDescription)

            }
        }
        DispatchQueue.main.async {
            print("Reload data")
            self.tableView.reloadData()
        }
    }

enter image description here

1 个答案:

答案 0 :(得分:1)

您需要在dispatchGroup.enter()之前而不是在闭包内部调用getStockList

您还需要将dispatchGroup.leave移到stocks.forEach之外:

fetch { stocks in
    self.hud.dismiss()

    dispatchGroup.enter()

    APIManager.shareInstance.getStockList(for: self.fetchedStocks) { result in
        switch result {
        case .success(let stocks):
            stocks.forEach { stock in
                for index in 0..<stocks.count {
                    self.fetchedStocks[index] = stock
                    print("Stock Model:", self.fetchedStocks[index])
                }
            }

        case .failure(let error):
            print(error.localizedDescription)
        }

        dispatchGroup.leave()
    }

    dispatchGroup.notify(queue: .main) {
        print("Sucessfully retrieve necessary data, now reloading tableview")
        self.tableView.reloadData()
    }
}   

或者,由于似乎getStockList仅被调用一次,所以您可以完全消除调度组:

fetch { stocks in
    self.hud.dismiss()

    APIManager.shareInstance.getStockList(for: self.fetchedStocks) { (result) in
        switch result {
        case .success(let stocks):
            stocks.forEach { (stock) in
                for index in 0..<stocks.count {
                    self.fetchedStocks[index] = stock
                    print("Stock Model:", self.fetchedStocks[index])
                }
            }

        case .failure(let error):
            print(error.localizedDescription)
        }

        DispatchQueue.main.async {
            print("Now reloading tableview")
            self.tableView.reloadData()
        }
    }
}

请注意,如果DispatchQueue.main.async已在主队列上调用此闭包,则不需要fetch。而且,如果未在主队列上调用它,那么您可能还希望将self.fetchedStocks的更新分派到主队列,以确保此模型对象的线程安全。


我不确定您为什么要遍历stocks。我本以为就足够了:

fetch { stocks in
    self.hud.dismiss()

    APIManager.shareInstance.getStockList(for: self.fetchedStocks) { (result) in
        switch result {
        case .success(let stocks):
            DispatchQueue.main.async {
                self.fetchedStocks = stocks
                self.tableView.reloadData()
            }

        case .failure(let error):
            print(error.localizedDescription)
        }
    }
}

同样,如果DispatchQueue.main.async完成处理程序已经在主队列上运行,则不需要fetch