加载 tableview 时应用程序崩溃并显示错误“无效更新:无效的节数”。

Posted

技术标签:

【中文标题】加载 tableview 时应用程序崩溃并显示错误“无效更新:无效的节数”。【英文标题】:App crashing when loading tableview with the error "Invalid update: invalid number of sections." 【发布时间】:2017-05-04 05:56:24 【问题描述】:

应用程序崩溃并显示以下错误:

无效更新:节数无效。段数 更新后的表视图中包含的 (6) 必须等于 更新前表格视图中包含的部分数(3), 加上或减去插入或删除的节数(0 插入, 0 已删除)。请帮忙

我的代码:

func numberOfSections(in tableView: UITableView) -> Int 

    return newsArray.count



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

    return 1


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 


    let cell = tableView.dequeueReusableCell(withIdentifier: "CellID", for: indexPath) as? NewsTableViewCell


    cell?.contentView.backgroundColor = UIColor.clear

    let whiteRoundedView : UIView = UIView(frame: CGRect(x: 10, y: 4, width: self.view.frame.size.width - 20, height: 410))

    whiteRoundedView.layer.backgroundColor = CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(), components: [1.0, 1.0, 1.0, 0.9])
    whiteRoundedView.layer.masksToBounds = false
    whiteRoundedView.layer.cornerRadius = 2.0
    whiteRoundedView.layer.shadowOffset = CGSize(width: -1, height: 1)
    whiteRoundedView.layer.shadowOpacity = 0.2

    cell?.contentView.addSubview(whiteRoundedView)
    cell?.contentView.sendSubview(toBack: whiteRoundedView)

    let newsdata = newsArray[indexPath.section]

    let date = NSDate(timeIntervalSince1970: TimeInterval(newsdata.meta))
    let dayTimePeriodFormatter = DateFormatter()
    dayTimePeriodFormatter.dateFormat = "MMM dd YYYY "

    let dateString = dayTimePeriodFormatter.string(from: date as Date)


    print(dateString)

    if let newsImg = self.newsImageCache.object(forKey: indexPath.section as AnyObject)
        cell?.imageOut.image = newsImg as? UIImage
     else 
        loadImageFromWeb(uri: newsdata.photo, cache: self.newsImageCache, indexpath: indexPath)

    
    cell?.titleLabel.text = newsdata.title
    cell?.descLabel.text = newsdata.body


    return cell!





 func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 

    if indexPath.section + 3 == self.newsArray.count 

        loadDatafromUrl()
    




func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 
    return 20


// Make the background color show through
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
    let headerView = UIView()
    headerView.backgroundColor = UIColor.clear
    return headerView




func loadDatafromUrl()
    let uri = "http://localhost/unani-info/admin/json/news.php"
    print(uri)
    if let url = URL(string: uri)

        let config = URLSessionConfiguration.default
        config.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
        let session = URLSession(configuration: config)

        let task = session.dataTask(with: url, completionHandler: 

            (rawData,response,error) in

            if error != nil 
                print("Couldnt load data")
                print(error?.localizedDescription as Any)

             else 
                if let data = rawData 
                    do
                        if let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [AnyObject]

                            for index in 0...json.count-1 

                                if let datas = json[index] as? [String: AnyObject] 

                                    let newsObj = News()
                                    newsObj.title = datas["title"] as! String
                                    newsObj.body = datas["body"] as! String
                                    let photo = datas["photo"] as! String
                                    let photourl = "http://localhost/unani-info/admin/uploads/" + photo
                                    newsObj.photo = photourl
                                    newsObj.meta = datas["meta"] as! Int

                                    self.newsArray.append(newsObj)


                                

                            
                            DispatchQueue.main.async 
                                self.tableView.reloadData()
                            

                        
                    catch
                        print("error")
                    
                
            
        )
        task.resume()
    


【问题讨论】:

【参考方案1】:

你能不能试试:

DispatchQueue.main.async 
    for index in 0...json.count-1 
        if let datas = json[index] as? [String: AnyObject] 
            let newsObj = News()
            newsObj.title = datas["title"] as! String
            newsObj.body = datas["body"] as! String
            let photo = datas["photo"] as! String
            let photourl = "http://localhost/unani-info/admin/uploads/" + photo
            newsObj.photo = photourl
            newsObj.meta = datas["meta"] as! Int
            self.newsArray.append(newsObj)
        
    
    self.tableView.reloadData()

代替:

for index in 0...json.count-1 
    if let datas = json[index] as? [String: AnyObject] 
        let newsObj = News()
        newsObj.title = datas["title"] as! String
        newsObj.body = datas["body"] as! String
        let photo = datas["photo"] as! String
        let photourl = "http://localhost/unani-info/admin/uploads/" + photo
        newsObj.photo = photourl
        newsObj.meta = datas["meta"] as! Int
        self.newsArray.append(newsObj)
    

DispatchQueue.main.async 
    self.tableView.reloadData()

【讨论】:

感谢您的回复,但是在tableview中加载数据需要花费太多时间。 能否请您推荐一个合适的tableview分页方法..? @YasheedMohammed 是否由于从服务器加载数据而导致加载延迟?如果是这样,您可以提前获取几页并显示。此外,如果尚未实现,请为图像实现延迟加载。【参考方案2】:

您正在反转 numberOfSectionsnumberOfRowsInSection。你应该有:

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


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return newsArray.count

【讨论】:

它的 bcz 我需要表格视图单元格之间的空间。这就是我喜欢这个的原因 如果您需要 tableViewCells 之间的空间,请使用tableView:heightForRowAtIndexPath: 了解更多详情,请查看developer.apple.com/reference/uikit/uitableviewdelegate/… tableView:heightForRowAtIndexPath: ,这是用于指定具有不同高度的行,不是吗?我没有任何可以动态改变其高度的单元格。我只需要在 facebook 新闻提要等单元格之间提供一个间隙 为此,您需要使用 UICollectionView 使用单列布局

以上是关于加载 tableview 时应用程序崩溃并显示错误“无效更新:无效的节数”。的主要内容,如果未能解决你的问题,请参考以下文章

使用致命错误刷新tableview时应用程序崩溃:索引超出范围Swift3

滚动表视图并单击搜索器崩溃应用程序

从图层重新加载 tableView 时崩溃

tableview reloadData在解包可选值时崩溃意外发现的nil

Tableview拖到底部时导致应用程序崩溃

为啥在我滚动显示来自 plist 的数据的 tableview 后我的应用程序崩溃?