Swift: уведомление DispatchGroup вызывается до завершения задачи - PullRequest
1 голос
/ 16 февраля 2020

Почему dispatchGroup.notify вызывается до того, как мои акции l oop? Разве его нельзя вызывать только после того, как задача выполнена? Ниже изображение моей консоли, чтобы показать вам, что я имею в виду.

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 Ответ

1 голос
/ 16 февраля 2020

Вам нужно позвонить 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 в основную очередь, чтобы обеспечить безопасность потоков этого объекта модели.


I Я не уверен, почему вы перебираете 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 уже запущен в главной очереди.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...