【问题标题】:Index out of range when trying to read an array of parsed JSON尝试读取解析的 JSON 数组时索引超出范围
【发布时间】:2017-06-27 20:50:25
【问题描述】:

我有一个从 NYTimes API 读取 JSON 的函数——我正在尝试用标题填充表格视图。这是函数:

func getJSON() {
    let url = NSURL(string: nyTimesURL)
    let request = NSURLRequest(url: url as! URL)
    let session = URLSession(configuration: URLSessionConfiguration.default)

    let task = session.dataTask(with: request as URLRequest) { (data, response, error) in

        if error != nil {
            print(error)
        }

        let json = JSON(data: data!)
        let results = json["results"].arrayValue

        for title in results {

            let titles = title["title"].stringValue
            print(titles)

            let count: Int = title.count
            self.numberOfStories = count

            self.headlines.append(titles)
            self.tableView.reloadData()
            print("\n\n\nHeadlines array: \(self.headlines)\n\n\n")
        }
    }
    task.resume()
}

然后作为类变量我有

var headlines = [String]()
var numberOfStories = 1

如果我对 cell.textLabel 进行硬编码,我可以运行应用程序并看到 headlines 数组正确填充了所有标题。但是,如果我尝试将单元格标签设置为self.headlines[indexPath.row],则会出现索引超出范围崩溃。我已经尝试将 tableView.reloadData() 调用放在主线程 (DispatchQueue.main.async{}) 中,但这不是问题。

如何让标题正确显示?

感谢您的帮助!

编辑:表格视图方法:

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.numberOfStories
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "JSONcell", for: indexPath) as! JSONTableViewCell

    cell.cellLabel.text = self.headlines[indexPath.row]


    return cell
}

【问题讨论】:

  • 您发布的代码均未尝试访问数组。你在哪里打电话给self.headlines[indexPath.row]?您何时何地致电getJSON
  • 而且你必须使用DispatchQueue.main.async从数据任务完成块内部调用reloadData
  • @rmaddy 我添加了我的 tableview 方法 - 我在我的 cellForRow 方法中调用 self.headlines[indexPath.row] 来设置标签。
  • 将 reloadData 调用放入 DispatchQueue.main.async 似乎并没有什么不同。
  • 所有 UI 更新必须在主队列上完成。

标签: ios json swift uitableview


【解决方案1】:

您需要摆脱您的 numberOfStories 属性。请改用headlines.count

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

您的cellForRowAtnumberOfRowsInSection 必须基于相同的数据。

并确保在DispatchQueue.main.async 中调用reloadData,因为数据任务完成块是从后台队列调用的。

【讨论】:

  • 好的,我明白了 - numberOfStories 有点多余。我进行了更改,现在可以使用了,谢谢!确认一下,self.tableView.reloadData() 在这里的正确位置(在 for 循环中)?我在它周围添加了DispatchQueue.main.async,我只是想确保它在循环内。
  • 实际上对reloadData的调用必须在for循环之后。为每个添加的项目重新加载整个表是没有意义的。添加所有项目后重新加载一次。
猜你喜欢
  • 2017-01-26
  • 2019-06-04
  • 1970-01-01
  • 1970-01-01
  • 2015-04-19
  • 2017-05-28
  • 2020-09-21
  • 2022-01-03
  • 2021-06-26
相关资源
最近更新 更多