Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 删除包含CoreData和NSFetchedResultsController的UITableView行_Ios_Swift_Core Data_Swift3 - Fatal编程技术网

Ios 删除包含CoreData和NSFetchedResultsController的UITableView行

Ios 删除包含CoreData和NSFetchedResultsController的UITableView行,ios,swift,core-data,swift3,Ios,Swift,Core Data,Swift3,尝试从tableView中删除行后,应用程序将终止,出现以下错误: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (2) mu

尝试从tableView中删除行后,应用程序将终止,出现以下错误:

Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'Invalid update: invalid
number of rows in section 0.  The number of rows contained in an
existing section after the update (2) must be equal to the number of
rows contained in that section before the update (2), plus or minus
the number of rows inserted or deleted from that section (0 inserted,
1 deleted) and plus or minus the number of rows moved into or out of
that section (0 moved in, 0 moved out).'
代码如下:

import UIKit
import CoreData

class PlayerTableViewController: UITableViewController {


lazy var fetchedResultsController:NSFetchedResultsController<TCSpieler> = {
    let fetch:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "TCSpieler")
    let sortByName = NSSortDescriptor(key: "name", ascending: true)
    fetch.sortDescriptors = [sortByName]
    let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    let frc = NSFetchedResultsController(fetchRequest: fetch, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
    try! frc.performFetch()
    return frc as! NSFetchedResultsController<TCSpieler>
}()

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    return fetchedResultsController.sections?.count ?? 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return fetchedResultsController.sections![section].numberOfObjects
}

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

    let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerCell", for: indexPath) as! PlayerTableViewCell
    // Configure the cell...
    cell.player = fetchedResultsController.object(at: indexPath)

    return cell
}


// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    // Return false if you do not want the specified item to be editable.
    return true
}

// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
    let rowToDelete = fetchedResultsController.object(at: indexPath)
    fetchedResultsController.managedObjectContext.delete(rowToDelete)
        try! fetchedResultsController.managedObjectContext.save()

        // Delete the row from the data source
        tableView.deleteRows(at: [indexPath], with: .fade)
    } 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
    }

}
导入UIKit
导入CoreData
类PlayerTableViewController:UITableViewController{
惰性变量fetchedResultsController:NSFetchedResultsController={
let fetch:NSFetchRequest=NSFetchRequest(entityName:“TCSpieler”)
让sortByName=NSSortDescriptor(键:“名称”,升序:true)
fetch.sortDescriptors=[sortByName]
让managedObjectContext=(UIApplication.shared.delegate为!AppDelegate)。persistentContainer.viewContext
设frc=NSFetchedResultsController(fetchRequest:fetch,managedObjectContext:managedObjectContext,sectionNameKeyPath:nil,cacheName:nil)
试试!frc.performFetch()
将frc返回为!NSFetchedResultsController
}()
//标记:-表视图数据源
重写func numberOfSections(在tableView:UITableView中)->Int{
返回fetchedResultsController.sections?.count?1
}
重写func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
返回fetchedResultsController.sections![section].numberOfObjects
}
重写func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
让cell=tableView.dequeueReusableCell(标识符为:“PlayerCell”,用于:indexPath)作为!PlayerTableViewCell
//配置单元格。。。
cell.player=fetchedResultsController.object(位于:indexPath)
返回单元
}
//替代以支持表视图的条件编辑。
重写func tableView(tableView:UITableView,canEditRowAt indexath:indexPath)->Bool{
//如果不希望指定的项可编辑,则返回false。
返回真值
}
//替代以支持编辑表格视图。
重写func tableView(tableView:UITableView,commit editingStyle:UITableViewCellEditingStyle,forRowAt indexPath:indexPath){
如果editingStyle==.delete{
让rowToDelete=fetchedResultsController.object(位于:indexPath)
fetchedResultsController.managedObjectContext.delete(rowToDelete)
试试!fetchedResultsController.managedObjectContext.save()
//从数据源中删除该行
tableView.deleteRows(位于:[indexPath],带:.fade)
}如果editingStyle==,则为else。插入{
//创建相应类的新实例,将其插入数组,并向表视图添加新行
}
}
这对我很有用:

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

        if editingStyle == UITableViewCellEditingStyle.delete {
            let managedObjectContext: NSManagedObjectContext = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext;
            let managedObject: NSManagedObject = fetchedResultsController.object(at: indexPath) as! NSManagedObject;
            managedObjectContext.delete(managedObject);
            do {
                try managedObjectContext.save();
                tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.fade);
            } catch {
                // Error occured while deleting objects
            }



        } else if editingStyle == UITableViewCellEditingStyle.insert {

        }

    }
这在swift 4中起作用

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

        if editingStyle == UITableViewCellEditingStyle.delete {
            let managedObjectContext: NSManagedObjectContext = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext;
            let managedObject: NSManagedObject = fetchedResultsController.object(at: indexPath) as! NSManagedObject;
            managedObjectContext.delete(managedObject);
            do {
                try managedObjectContext.save();
            } catch {
                // Error occured while deleting objects
            }



        } else if editingStyle == UITableViewCellEditingStyle.insert {

        }

}
此外,以下内容将负责更新UI 当数据库更新时

extension PlayerTableViewController: NSFetchedResultsControllerDelegate {

    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        self. tableView.beginUpdates()
    }

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

        switch type {
        case .insert:
            self. tableView.insertRows(at: [newIndexPath! as IndexPath], with: .fade)
        case .delete:
            self. tableView.deleteRows(at: [indexPath! as IndexPath], with: .fade)
        case .update:
            if(indexPath != nil) {
                let cell = self. tableView.cellForRow(at: indexPath! as IndexPath)
            }
        case .move:
            self. tableView.deleteRows(at: [indexPath! as IndexPath], with: .fade)
            self. tableView.insertRows(at: [indexPath! as IndexPath], with: .fade)
        }
    }

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        self. tableView.endUpdates()
    }

}
扩展PlayerTableViewController:NSFetchedResultsControllerDelegate{
func controllerWillChangeContent(\ucontroller:NSFetchedResultsController){
self.tableView.beginUpdate()
}
func控制器(controller:NSFetchedResultsController,didChange anObject:Any,在indexPath:indexPath?处,对于类型:NSFetchedResultsChangeType,newIndexPath:indexPath?){
开关类型{
案例.插入:
self.tableView.insertRows(位于:[newindexath!as indexath],带:.fade)
案例.删除:
self.tableView.deleteRows(位于:[indexath!as indexath],带:.fade)
案例。更新:
if(indexPath!=nil){
让cell=self.tableView.cellForRow(at:indexPath!as indexPath)
}
案件.动议:
self.tableView.deleteRows(位于:[indexath!as indexath],带:.fade)
self.tableView.insertRows(位于:[indexPath!as indexPath],带:.fade)
}
}
func controllerDidChangeContent(\控制器:NSFetchedResultsController){
self.tableView.endUpdates()
}
}

尝试使用断点并检查是否从
fetchedResultsController
中删除数据。是否实现了
NSFetchedResultsController
的委托方法?删除前第2节中有多少行?