2016-12-10 8 views
0

私はTableCellを作成する前にJSON呼び出しを取得しようとしていますが、ディスパッチキューを使用してコールブロックを作成することはできません。私はどのように私はそれがgroup.wait()行で停止するように助言してください下に掲載されたコードです。JSON呼び出し後にディスパッチグループがブロックされない

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) 
    } 
} 
+1

「cellForRowAt」をブロックすることは恐ろしいことです。恐ろしい使用経験があるからです。 JSONをviewDidLoad **に非同期的にロード**してから、テーブルビューをリロードしてください。 – vadian

答えて

0

あなたがいないクロージャの内部で、あなたの要求を実行する前にgroup.enter()を呼び出す必要があります。


しかしAlamofireは、その完了ハンドラのメインキューを使用していますので、あなたがメインキューにwait完了ハンドラがleave()を呼び出すまでならば、あなたはデッドロックます。この「待機」パターンを本当に使用したい場合は、requestが完了ハンドラにそのバックグラウンドキューを使用するように指定する必要があります。


はそれはとても直感的waitに訴えていますが、これはそれの適切な使用ではない、と述べました。 (セマフォーを使用した論理的に同等の解決策でもありません)

ネットワーク要求を開始し、非同期にセルを更新する必要があります。しかし、cellForRowAtIndexPathはネットワーク要求を待つべきではありません。


私は代替実装を提案するつもりだったが、それはあなたが今(何をしようとして完全には明らかではありません、あなたがいないよう、テーブルのすべての行のための別のネットワーク要求をやっています右)。 LocationDataはどこから来たのですか?場所の名前を取得する1つの要求を本当にしたいと思う場合は、その要求をviewDidLoadに移動して、完了ハンドラでtableView.reload()を呼び出します。

var locations: [String]? 

override func viewDidLoad() { 
    super.viewDidLoad() 

    Alamofire.request("http://localhost:3000/locations.json").responseJSON { response in 
     guard response.result.error == nil else{ 
      print("Error: unable to get a list of locations.") 
      return 
     } 
     if let result = response.result.value as? [[String: Any]] { 
      self.locations = result.map { $0["name"] as! String } 
      self.tableView.reloadData() 
     } 
    } 
} 

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return locations?.count ?? 0 
} 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Picture", for: indexPath) 
    cell.textLabel?.text = locations?[indexPath.row] 
    return cell 
} 
+0

ロブ、あなたは天才です - ありがとう、私は金曜日以来これに取り組んでいます(私はおそらく15時間かけてそれを理解しようとしました)。私はまだSwiftについて学ぶことがたくさんありますし、Ruby on Railsのバックグラウンドから来た後は崖の上を歩くのと同じように正直言って...... – jonnylawrence

+0

問題はありません。ちなみに、私があなたの質問に答えた場合は、その隣のチェックマークをクリックして答えを受け入れることを検討してください。 「誰かが私の質問に答えるとき、私は何をすべきですか?」(http://stackoverflow.com/help/someone-answers) – Rob

+0

また、Swiftの非同期パターンに慣れるまでに時間がかかりそうだとは思わないでください。あなたがそれを数回してこれらのパターンに慣れれば、おそらく第二の性質のように感じるでしょう。 – Rob

関連する問題