我在VC中有一个表视图。它使用以下代码从核心数据对象填充:
// Variables
var allFruits: NSArray
var managedObjectContext: NSManagedObjectContext
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
func loadFruits(){
// Try to load all of the Fruits from the core data.
let fetchRequest = NSFetchRequest()
let entityDescription = NSEntityDescription.entityForName("Fruit", inManagedObjectContext: self.managedObjectContext)
fetchRequest.entity = entityDescription
do{
self.allFruits = try self.managedObjectContext.executeFetchRequest(fetchRequest)
if self.allFruits.count == 0{
print("No saved Fruits")
}
}
catch
{
let fetchError = error as NSError
print(fetchError)
}
}
然后使用此特定水果数据填充表格视图。我有这种方法从表中删除水果
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
// handle delete (by removing the data from your array and updating the tableview)
managedObjectContext.deleteObject(allFruits[indexPath.row] as! NSManagedObject)
// Attempt to save the object
do{
try appDelegate.managedObjectContext.save()
}
catch let error{
print("Could not save Deletion \(error)")
}
// Remove the deleted item from the table view
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
// Reload the fruits
self.loadFruits()
// Reload the table view
tableView.reloadData()
}
}
每次我尝试删除水果时,这都会导致应用程序崩溃。
'NSInternalInconsistencyException',原因:'无效更新:无效 第0节中的行数。包含在中的行数 更新后的现有部分(5)必须等于数量 更新前的该部分中包含的行(5),加号或减号 从该部分插入或删除的行数(插入0, 删除1)加上或减去移入或移出的行数 该部分(0移入,0移出)。'
我怀疑我使用NSArray
而不是NSMutableArray
这一事实存在一些问题。
如何解决此问题?
提前致谢。
答案 0 :(得分:2)
首先使用Swift数组而不是Foundation数组
var allFruits = [NSManagedObject]()
这避免了大量的类型转换。
要使Core Data和表格视图保持同步,您必须删除模型中Core Data 和中的对象。完全重新加载模型和视图的解决方案非常昂贵,根本不需要。
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
let objectToDelete = allFruits[indexPath.row]
allFruits.removeAtIndex(indexPath.row)
managedObjectContext.deleteObject(objectToDelete)
//Attempt to save the object
do{
try appDelegate.managedObjectContext.save()
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
catch let error{
print("Could not save Deletion \(error)")
}
}
}
deleteRowsAtIndexPaths
包括更新UI,因此不需要重新加载表视图。
如果表格视图的模型为NSManagedObject
,建议您使用NSFetchedResultsController
答案 1 :(得分:1)
您应该在删除之前更新数据源。像这样:
//Reload the fruits
self.loadFruits()
//Remove the deleted item from the table view
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
如果您确定没有其他更改,则无需重新加载数据,因为这会花费很多。
答案 2 :(得分:0)
我只需更改此方法即可修复我的代码:
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
// handle delete (by removing the data from your array and updating the tableview)
managedObjectContext.deleteObject(allFruits[indexPath.row] as! NSManagedObject)
//Attempt to save the object
do{
try appDelegate.managedObjectContext.save()
}
catch let error{
print("Could not save Deletion \(error)")
}
//Reload the fruits
self.loadFruits()
//Reload the table view
tableView.reloadData()
}
}
这成功地从核心数据中删除对象以及更新表视图。
答案 3 :(得分:0)
针对Swift 3 Xcode 8 iOS 10进行了更新
以下代码段添加“轻扫”以删除'到表行,并将更改保存到CoreData。
<hr>