从TableView

时间:2018-01-21 17:31:03

标签: ios core-data tableview swift4

我有十几个表视图控制器都按预期工作,然后我有一个崩溃了:

由于未捕获的异常终止应用程序' NSInternalInconsistencyException',原因:'无效更新:第0部分中的行数无效。更新后现有部分中包含的行数(1)必须等于更新前的该部分中包含的行数(1),加上或减去从该部分插入或删除的行数(0插入,1删除)和加或减移入的行数或超出该部分(0移入,0移出)。'

执行此操作的代码已使用不同的选项进行了多次修改,但没有效果。

import UIKit
import CoreData

class QTypeVCY: UITableViewController, NSFetchedResultsControllerDelegate
{
    let app = UIApplication.shared.delegate as! AppDelegate

    override func viewDidLoad()
    {
        super.viewDidLoad()
    }

    override func numberOfSections(in tableView: UITableView) -> Int
    {
        let sections = frc.sections
        return sections!.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        guard let sections = self.frc.sections else
        {
            fatalError("No sections in fetchedResultsController")
        }
        let sectionInfo = sections[section]
        return sectionInfo.numberOfObjects
    }

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

        let qtype = frc.object(at: indexPath)
        cell.textLabel?.text = qtype.title

        return cell
    }

    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete
        {
            do
            {
                let qtype = frc.object(at: indexPath)
                let context = self.frc.managedObjectContext
                context.delete(qtype)
                try context.save()
                tableView.deleteRows(at: [indexPath], with: .fade)
            }
            catch
            {
                debugPrint(error)
            }
        } else if editingStyle == .insert
        {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }

    lazy var frc: NSFetchedResultsController<Qtype> =
        {
            let context = self.app.persistentContainer.viewContext
            let req: NSFetchRequest<Qtype> = Qtype.fetchRequest()
            req.fetchBatchSize = 10

            let sortDescriptor1 = NSSortDescriptor(key: #keyPath(Qtype.specialty), ascending:true)
            let sortDescriptor2 = NSSortDescriptor(key: #keyPath(Qtype.title), ascending:true)
            req.sortDescriptors = [sortDescriptor1, sortDescriptor2]

            let afrc = NSFetchedResultsController(fetchRequest: req, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)

            afrc.delegate = self
            do
            {
                try afrc.performFetch()
            }
            catch
            {
                print(error.localizedDescription)
                fatalError("Abort while fetching Qtype")
            }
            return afrc
    }()
}

崩溃发生在tableview.deleteRows语句中。我试过用beginUpdate / endUpdates包围代码,有和没有performFetch,甚至尝试重新输入代码,以防我错过了一个错字。这个相同的基本代码在其他表/视图控制器上工作正常,只有这一个。

实体只是由字符串组成。我和其他实体有关系,没有关系。

Qtype Entity

自从下次运行应用程序时,该行将被删除。此外,关于此表的另一个问题是在添加新对象后调用reloadData不会添加该行。我需要离开tableview并重新输入。我确定这两者是相关的,但不能说出原因。

由于最初发布此内容,我包含了整个VC代码,而不仅仅是违规代码。我也尝试用不同的实体交换实体,但这个问题没有发生,但程序仍然崩溃,即使是不同的实体。

3 个答案:

答案 0 :(得分:1)

您忘记从数据源数组

中删除该项目
let qtype = qtypes[indexPath.row]
let context = self.frc.managedObjectContext
context.delete(qtype)
try context.save()
qtypes.remove(at: indexPath.row) // <-- 
tableView.deleteRows(at: [indexPath], with: .fade)

答案 1 :(得分:0)

我希望我能提供实际的解决方案,但上面的代码现在可以使用了。我已经将XCode更新为1/24/18版本,但我不认为这是解决方案。我还删除了我在原始代码中崩溃的一些东西,但后来我把它们放回去了它仍然可以工作。我怀疑我在某个地方有一个错字,但在花了半个小时试图找到它之后,我宣布胜利并继续前进。

答案 2 :(得分:0)

我刚刚解决了一个与您相似的问题。 在CoreData中删除数据时,TableView数据数组也将在appDelegate.saveContext()

之前删除

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath)中的代码

self.tableviewArrayData.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
appDelegate.saveContext()