尝试读取解析的 JSON 数组时索引超出范围

Posted

技术标签:

【中文标题】尝试读取解析的 JSON 数组时索引超出范围【英文标题】:Index out of range when trying to read an array of parsed 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 更新必须在主队列上完成。 【参考方案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循环之后。为每个添加的项目重新加载整个表是没有意义的。添加所有项目后重新加载一次。

以上是关于尝试读取解析的 JSON 数组时索引超出范围的主要内容,如果未能解决你的问题,请参考以下文章

索引超出范围错误(从文件中读取的数组)

SwiftUI:JSON 索引总是超出范围

来自数组索引的表视图超出范围

致命错误:在Swift中访问10个元素的数组时,数组索引超出范围

从firebase删除时数组索引超出范围

致命错误:数组索引超出范围。刷新时迅速