【问题标题】:In Swift, tableView data loaded from JSON only loads 80% of the time在 Swift 中,从 JSON 加载的 tableView 数据只加载了 80% 的时间
【发布时间】:2016-05-27 02:05:26
【问题描述】:

我正在用 JSON 数据填充我的 tableView,大多数时候数据会显示,但由于某些奇怪的原因,有时它不会。我在 Chrome 中测试了 JSON 数据,信息就在那里。我还做了打印声明以在下载信息后打印信息,并且似乎下载正确。我无法弄清楚为什么 80% 的数据正确填充 tableView 而 20% 的时间却没有。这是我的代码示例,还有更多单元格,但在此示例中我将其缩短为 2:

    var task : NSURLSessionTask?
    var newURL : String? 
    var bannerArray: [String] = []
    var overViewArray: [String] = []

override func viewDidLoad() {
    super.viewDidLoad()

    getJSON(newURL!)

  }

      func getJSON (urlString: String) {

        let url = NSURL(string: urlString)!
        let session = NSURLSession.sharedSession()
        task = session.dataTaskWithURL(url) {(data, response, error) in
          dispatch_async(dispatch_get_main_queue()) {
            if (error == nil) {
              self.updateDetailShowInfo(data)
            }
            else {
              "Not getting JSON"
            }
          }
        }
        task!.resume()
      }


     func updateDetailShowInfo (data: NSData!) {
        do {
          let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary

          guard let banner = jsonResult["banner"] as? String,
          let overview = jsonResult["overview"] as? String 
          else { return }
          _ = ""

          print(overview)

          bannerArray.append(banner)
          overViewArray.append(overview)
     }
        catch {
          print("It ain't working")
        }
        self.DetailTvTableView.reloadData()
        }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 2
      }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        switch section {
        case 0: return bannerArray.count
        case 1: return overViewArray.count
        default: fatalError("Unknown Selection")
        }
      }

      override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = UITableViewCell()

        switch indexPath.section {

        case 0:
          let cell = tableView.dequeueReusableCellWithIdentifier("bannerCell", forIndexPath: indexPath) as! BannerCell
          cell.bannerImage.sd_setImageWithURL(NSURL(string: bannerArray[indexPath.row]))
          self.DetailTvTableView.rowHeight = 100
          DetailTvTableView.allowsSelection = false
          return cell

        case 1:
          let cell = tableView.dequeueReusableCellWithIdentifier("overviewCell", forIndexPath: indexPath) as! OverviewCell
          let overViewText = overViewArray[indexPath.row]
          if overViewText != "" {
            cell.overView.text = overViewText
          } else {
            cell.overView.text = "N/A"
          }
          self.DetailTvTableView.rowHeight = 200

          print(overViewArray[indexPath.row])
          return cell

     default: ""
        }
        return cell
      }

【问题讨论】:

  • 你能定义“不工作”吗?该代码的哪些部分在运行时运行或不运行?
  • tableView 似乎没有呈现 JSON 数据。它根本不显示任何单元格。奇怪的是,它只是有时会这样做,大部分时间都有效。
  • 所以它仍在加载 JSON,只是没有显示它?也就是说,updateDetailShowInfo 仍然被调用并正常工作?
  • 是的,情况似乎如此,尽管由于某些奇怪的原因 self.DetailTvTableView.reloadData() 并不总是被调用。
  • 有几个代码路径不会调用 reloadData。例如,您的 guard 可能失败或 JSON 错误不为零。你有没有通过代码来查看它的发展方向?

标签: ios json swift uitableview tableview


【解决方案1】:

我只是在网上做这个。而且我认为有一些错误。您需要自己调试它们。

您对获取 JSON 和 GCD 的理解是完全错误的。我相信这些代码是你从网上某个地方得到的。去看看dispatch_async是什么。

基本上,您需要创建会话来获取 JSON 数据,您已经正确地完成了它,但是,在 NSJSONSerialization 中,您需要将它们存储在一个变量中并将其附加到您的数组中。这是异步获取的。您的 dispatch_async 将串行重新加载数据。

func getJSON (urlString: String) {
    let url = NSURL(string: urlString)!
    let session = NSURLSession.sharedSession()
    task = session.dataTaskWithURL(url) {(data, response, error) in
    let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
        guard let banner = jsonResult["banner"] as? String,
        let overview = jsonResult["overview"] as? String 

        bannerArray.append(banner)
        overViewArray.append(overview)
     } dispatch_async(dispatch_get_main_queue()) {
            if (error == nil) {
              self.DetailTvTableView.reloadData()
            }
            else {
              "Not getting JSON"
            }
          }
    catch {
        print("It ain't working")
            }

            }
        }
        task!.resume()
}

【讨论】:

  • 代码示例工作得更好一些,其中一个没有填充数据的单元现在可以了。虽然当我在 self.DetailTVTableView.reloadData() 点设置断点时,它显示除了一个数组之外的所有数组都是空的,即使 JSON 数据下载正确。知道为什么会发生这种情况吗?
  • 那是哪个数组?你把它放在 NSJSONSerialization 里面了吗?
  • 在下载下一段 json 数据之前,在 json 数据下载后立即附加数组后,它就开始工作了。为什么有些我可以批量下载和追加,而另一些除非单独下载和追加才能工作,这很奇怪。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多