【发布时间】:2018-07-25 07:13:02
【问题描述】:
在更新 UI 之前需要等待一些 api 调用循环完成,但还不知道为什么我的 DispatchGroup.notify() 在 http 调用之前被执行:
override func viewDidAppear(_ animated: Bool) {
if isFirstLoad {
ProgressIndicator.shared.showProgressView(self.view)
let serviceUrl = MobnerServices.service_base+"GetTrainersAround?lat=\(self.currLatitude!)&lon=\(self.currLongitude!)&radius=50"
Alamofire.request(serviceUrl).responseJSON{ response in
do{
guard let responseData = response.data else{
print("No data received.")
ProgressIndicator.shared.hideProgressView()
return
}
let dispatchGroup = DispatchGroup()
let decoder = JSONDecoder()
let retrievedTrainers = try decoder.decode([STTrainer].self, from: responseData)
self.trainers = retrievedTrainers
self.isFirstLoad = false
for trainer in self.trainers{
dispatchGroup.enter()
let getUserPictureUrl = MobnerServices.service_base+"GetUserPicture?filename=\(trainer.profilePicturePath)"
Alamofire.request(getUserPictureUrl).responseImage { response in
guard let image = response.result.value else {
print(response.error!.localizedDescription)
return
}
self.trainersPictures.append(STTrainerPicture(userId: trainer.userId, profilePicture: image))
}
dispatchGroup.leave()
}
dispatchGroup.wait()
ProgressIndicator.shared.hideProgressView()
self.tableView.reloadData()
}
catch{
print(error.localizedDescription)
}
}
}
}
这里有人给点建议吗? 提前致谢!
【问题讨论】:
-
你的代码中没有
DispatchGroup.notify,那么我们到底在说什么? -
我在一些博客中看到我们可以使用 .wait() 而不是 .notify()。
-
我们当然可以使用
wait而不是notify,但是您的问题不应该问为什么不调用notify。没有notify。 -
Guilherme,这些博客具有误导性,因为使用
wait几乎总是错误的方法。较新的开发人员喜欢wait,因为它简单直观,但会导致糟糕的用户体验并可能带来问题。在此示例中,您将在wait处阻塞主线程,因此您将死锁,因为 Alamofire 将无法在该阻塞的主队列上运行其完成处理程序,因此,您将永远无法到达那个leave电话,它永远不会超过那个@ 987654331@。notify模式避免了阻塞主线程,避免了这个问题。 -
@Rob,这是真的。我注意到当使用 .wait() 时,用户界面甚至不会被错误地更新。