Ios 从TableView中删除行时CoreData应用程序崩溃
我有十几个表视图控制器,它们都能按预期工作,然后我有一个崩溃了: 由于未捕获异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:节0中的行数无效。”。更新(1)后现有节中包含的行数必须等于更新(1)前该节中包含的行数,加上或减去从该节中插入或删除的行数(0插入,1删除),加上或减去移入或移出该节的行数(0移入,0移出).' 执行此操作的代码已使用不同的选项进行了多次修改,但没有任何效果Ios 从TableView中删除行时CoreData应用程序崩溃,ios,core-data,tableview,swift4,Ios,Core Data,Tableview,Swift4,我有十几个表视图控制器,它们都能按预期工作,然后我有一个崩溃了: 由于未捕获异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:节0中的行数无效。”。更新(1)后现有节中包含的行数必须等于更新(1)前该节中包含的行数,加上或减去从该节中插入或删除的行数(0插入,1删除),加上或减去移入或移出该节的行数(0移入,0移出).' 执行此操作的代码已使用不同的选项进行了多次修改,但没有任何效果 import UIKit import CoreData
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
}()
}
导入UIKit
导入CoreData
类QTypeVCY:UITableViewController,NSFetchedResultsControllerDelegate
{
将app=UIApplication.shared.delegate设为!AppDelegate
重写func viewDidLoad()
{
super.viewDidLoad()
}
重写func numberOfSections(在tableView:UITableView中)->Int
{
设截面=frc截面
返回节数
}
重写func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int
{
防护罩let部分=自frc部分其他部分
{
fatalError(“fetchedResultsController中没有节”)
}
让sectionInfo=节[节]
返回sectionInfo.numberOfObjects
}
重写func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell
{
let cell=tableView.dequeueReusableCell(标识符为“qqq”,表示:indexath)
让qtype=frc.object(at:indepath)
cell.textlab?.text=qtype.title
返回单元
}
重写func tableView(tableView:UITableView,commit editingStyle:UITableViewCellEditingStyle,forRowAt indexPath:indexPath){
如果editingStyle==.delete
{
做
{
让qtype=frc.object(at:indepath)
让context=self.frc.managedObjectContext
context.delete(qtype)
尝试context.save()
tableView.deleteRows(位于:[indexPath],带:.fade)
}
抓住
{
调试打印(错误)
}
}如果editingStyle==,则为else。插入
{
//创建相应类的新实例,将其插入数组,并向表视图添加新行
}
}
惰性变量frc:NSFetchedResultsController=
{
让context=self.app.persistentContainer.viewContext
let-req:NSFetchRequest=Qtype.fetchRequest()
req.fetchBatchSize=10
让SortDescriptor 1=NSSortDescriptor(键:#键路径(Qtype.speciality),升序:true)
让SortDescriptor 2=NSSortDescriptor(键:#键路径(Qtype.title),升序:true)
req.sortDescriptors=[sortDescriptor1,sortDescriptor2]
设afrc=NSFetchedResultsController(fetchRequest:req,managedObjectContext:context,sectionNameKeyPath:nil,cacheName:nil)
afrc.delegate=self
做
{
试试afrc.performFetch()
}
抓住
{
打印(错误。本地化描述)
fatalError(“获取Qtype时中止”)
}
返回afrc
}()
}
崩溃发生在tableview.deleteRows语句中。我尝试过使用beginUpdate/endUpdates来包围代码,无论是否使用performFetch,甚至尝试过重新输入代码,以防我遗漏了一个输入错误。同样的基本代码也适用于其他表/视图控制器,仅此一个
实体只是由字符串组成的。我和其他实体有关系也有关系
自下次运行应用程序后,该行已被删除,但该行已丢失。此外,该表的另一个特点是,在添加新对象后调用reloadData不会添加行。我需要离开tableview并重新输入它。我确信这两者是相关的,但无法解释原因
由于最初发布了这篇文章,我包含了整个VC代码,而不仅仅是有问题的代码。我还尝试将该实体与未发生此问题的其他实体交换,但即使与其他实体交换,程序仍会崩溃。您忘了从数据源阵列中删除该项
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)
让qtype=qtypes[indexath.row]
让context=self.frc.managedObjectContext
context.delete(qtype)
尝试context.save()
qtypes.remove(位于:indexPath.row)/我希望能够提供实际的解决方案,但是上面的代码现在可以工作了。我已经将XCode更新为1/24/18版本,但我认为这不是解决方案。我还剥离了崩溃的原始代码中的一些内容,但后来我把它们放回原处,它仍然有效。我怀疑我在某个地方输入了一个错误,但花了半个小时试图找到它,我宣布胜利并继续前进。我刚刚解决了一个与你类似的问题。
删除CoreData中的数据时,TableView数据数组也会在appDelegate.saveContext()之前删除
func tableView中的代码(\tableView:UITableView,trailingswipeactions在indexath:indexPath中为行配置)
那没用。我应该显示更多的代码。数组qtypes不是全局的,它是从数据存储中检索的。但是,您必须从表示数据源数组的数组中删除该项。我尝试过这样做,但相同的问题仍然存在。我修改了示例以显示数组的来源。是否使用FetchedResultsController
的委托方法?如果是,则不能手动删除该行。如果sections
是值类型,则必须将qtype
重新分配给节。忘记beginUpdates
和endUpdates
self.tableviewArrayData.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
appDelegate.saveContext()