当我已经更新数据时出现错误“无效更新:无效行数”

Posted

技术标签:

【中文标题】当我已经更新数据时出现错误“无效更新:无效行数”【英文标题】:Have error "Invalid update: invalid number of rows" when I already updated the data 【发布时间】:2016-12-06 21:40:40 【问题描述】:

我的代码如下所示:

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 

    let IndexPaths = NSArray(array:[indexPath])

    let plistPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    let path = plistPath.appending("/ClassA.plist")
    self.listClasses.remove(at:indexPath.row)
    self.listClasses?.write(toFile: path, atomically: false)
    tableView.reloadData()
    self.tableView.deleteRows(at: IndexPaths as! [IndexPath], with: .fade)

我知道如果我不更新数据源中的数据会导致问题,所以我在更新 TableView 中的数据之前添加了这两行。

self.listClasses.remove(at:indexPath.row)
self.listClasses?.write(toFile: path, atomically: false)

但它仍然不起作用。我仍然收到此错误

'无效更新:第0节中的行数无效。更新后现有节中包含的行数(6)必须等于更新前该节中包含的行数(6),加上或减去从该节插入或删除的行数(0 插入,1 删除),加上或减去移入或移出该节的行数(0 移入,0 移出)。

有人知道为什么会这样吗?

下面是我的 TableView 代码

@IBAction func Edit(_ sender: Any) 
    setEditing(true, animated: true)


func tableView(_ tableView:UITableView, numberOfRowsInSection     selection:Int) -> Int 
    return self.listClasses.count


public func tableView(_ tableView: UITableView, cellForRowAt indexPath:IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath as IndexPath)
    let row = indexPath.row

    let rowDict = self.listClasses[row] as! NSDictionary

    cell.textLabel?.text = rowDict["name"] as? String
    return cell


override func viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib.
    super.viewDidLoad()

    let plistPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    let path = plistPath.appending("/ClassA.plist")
    let fileManager = FileManager.default
    if (!(fileManager.fileExists(atPath: path)))
    
        let bundle : String = Bundle.main.path(forResource: "ClassA", ofType: "plist")!
        do 
            try fileManager.copyItem(atPath: bundle as String, toPath: path)
        
        catch 
            NSLog("Error!")
        
    
    self.listClasses = NSMutableArray(contentsOfFile:path)

    //set up the textfield
    self.txtField.isHidden = true
    self.txtField.delegate = self



override func setEditing(_ editing: Bool, animated: Bool) 
    super.setEditing(editing, animated: animated)
    self.tableView.setEditing(editing, animated:true)

//更新 现在我删除了“tableView.reloadData()”

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 

    let IndexPaths = NSArray(array:[indexPath])

    let plistPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    let path = plistPath.appending("/ClassA.plist")
    self.listClasses.remove(at:indexPath.row)
    self.listClasses?.write(toFile: path, atomically: false)
    self.tableView.deleteRows(at: IndexPaths as! [IndexPath], with: .fade)

但还是不行。

【问题讨论】:

either call reloadData or call deleteRows not both. @Paulw11 我试图删除其中一个(两种方式),但它仍然不起作用。 不,这是对所示代码的修复;您是否在其他地方删除该行?如果您删除 deleteRows,留下 reloadData 并且您仍然收到该消息,那么您将删除其他地方,因为 reloadData 永远不会导致该异常 【参考方案1】:

你有:

tableView.reloadData()
self.tableView.deleteRows(at: IndexPaths as! [IndexPath], with: .fade)

永远不要两者都做。只做其中之一。在这种情况下,最好这样做:

self.tableView.deleteRows(at: IndexPaths as! [IndexPath], with: .fade)

【讨论】:

这个方法应该在tableView.beginUpdates()和endUpdates()之间调用。不是吗? @BhavukJain 不,如果你多次调用delete/insert/reloadRows 的组合,你只需要使用begin/endUpdate @David 我建议的更改将解决问题。您是否删除了对reloadData 的呼叫?删除那行代码后的新错误是什么? 还是一样。 "'无效更新:第0节中的行数无效。更新后现有节中包含的行数(6)必须等于更新前该节中包含的行数(6),加或减从该部分插入或删除的行数(0 插入,1 删除)加上或减去移入或移出该部分的行数(0 移入,0 移出)。我在我的问题上发布了我的新代码。 这毫无意义。您显然正在为self.listClasses 删除一个对象,而您的numberOfRowsInSection 是基于self.listClasses。作为健全性检查,使用调试器查看在调用self.listClasses.remove(at:indexPath.row) 之前和之后self.listClasses 中的对象数量。你看到了什么?【参考方案2】:
extension UITableView 
     var dataHasChanged: Bool 
        guard let dataSource = dataSource else  return false 
        let sections = dataSource.numberOfSections?(in: self) ?? 0
        if numberOfSections != sections  return true 

        for section in 0..<sections 
            if numberOfRows(inSection: section) != dataSource.tableView(self, numberOfRowsInSection: section) 
                return true
            
        

        return false
     

用法:

 if tableView.dataHasChanged 
     tableView.reloadData()
  else 
     // Do anything what you want here
     // tableView.deleteRows(at: [indexPath], with: .none)
     // tableView.reloadRows(at: [indexPath], with: .none)
 

【讨论】:

以上是关于当我已经更新数据时出现错误“无效更新:无效行数”的主要内容,如果未能解决你的问题,请参考以下文章

Win10企业版安装NET Framework时出现"这台计算机中已经安装了.NET Framework 4.6.1或版本更高的更新"错误

System.Xml.XmlException '根级别的数据无效,第 1 行,位置 1' 当我从 1 个 xml 文件更改为 5 时出现错误

为啥当我点击更新按钮时出现错误TypeError: r is undefined?

为啥在尝试更新数据库时出现语法错误?

EF 更新大量的数据时出现重复键错误

在MySQL数据库中使用多个WHERE子句值更新多个列值时出现错误。