调度组在JSON调用后不会阻止

时间:2016-12-10 20:07:26

标签: swift uitableview grand-central-dispatch alamofire

我在填充TableCell之前试图让我的JSON调用返回,但是作为swift的新手,我无法使用调度队列调用阻止....有人可以建议如何我在下面发布的代码中的override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let queue:DispatchQueue = DispatchQueue.global() let group:DispatchGroup = DispatchGroup() Alamofire.request("http://localhost:3000/locations.json").responseJSON { response in group.enter() //print(response.request) // original URL request //print(response.response) // HTTP URL response //print(response.data) // server data //print(response.result) // result of response serialization guard response.result.error == nil else{ print("Error: unable to get a list of locations.") return } if let JSON = response.result.value { // print("JSON: \(JSON)") if let result = response.result.value as? [[String: Any]] { nameArray = result.map { ($0["name"] as? String)! } print(nameArray[0]) } } group.leave() } group.notify(queue: queue) { // This closure will be executed when all tasks are complete print("All tasks complete") } // synchronize on task completion by waiting on the group to block the current thread. print("block while waiting on task completion") let _ = group.wait() print("continue") let cell = tableView.dequeueReusableCell(withIdentifier: "Picture", for: indexPath) cell.textLabel?.text = LocationData[indexPath.row].name print (LocationData[indexPath.row].name) print(indexPath.row) // cell.textLabel?.text = nameArray[indexPath.row] return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if let vc = storyboard?.instantiateViewController(withIdentifier: "Detail") as? DetailViewController { vc.selectedImage = pictures[indexPath.row] navigationController?.pushViewController(vc, animated: true) } } 行停止了。

button.addEventListener('click', function() {
  var form = document.getElementById('form-id');

  event.preventDefault();

  // validations here

  if (validationsPassed) form.submit()
});

1 个答案:

答案 0 :(得分:0)

您必须在执行请求之前致电group.enter() ,而不是在闭包内。

但是因为Alamofire使用主队列作为其完成处理程序,如果你在主队列上wait,直到完成处理程序调用{​​{1}},你就会陷入僵局。如果您真的想使用这种“等待”模式,则必须指定leave()应该使用该后台队列作为其完成处理程序。

尽管如此,虽然它对request如此直观地吸引人,但这并不恰当地用于它。 (使用信号量的其他逻辑上等效的解决方案也不会。)

您应该启动网络请求,然后异步更新单元格。但是wait不应该等待网络请求。

我打算建议替代实现,但是你要做的事情并不完全清楚(现在,你正在为表的每一行做另一个网络请求,这似乎不正确)。 cellForRowAtIndexPath来自哪里?假设您确实想要一个请求来获取位置的名称,您可以将该请求移至LocationData,然后在完成处理程序中调用viewDidLoad

tableView.reload()