gpt4 book ai didi

swift - NSInternalInconsistencyException : Invalid Update using tableview CoreData

转载 作者:行者123 更新时间:2023-11-28 08:59:30 25 4
gpt4 key购买 nike

我正在使用 tableView 来显示人员列表。我正在尝试添加警报以确认用户确实想要删除此人并防止错误。但是,当我尝试删除存储在 CoreData 中的人时,重新加载 View 似乎出现问题。我得到这个异常(exception):由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:第 0 部分中的行数无效。更新 (2) 后现有部分中包含的行数必须等于行数在更新 (2) 之前包含在该部分中,加上或减去从该部分插入或删除的行数(0 插入,1 删除)以及加上或减去移入或移出该部分的行数(0 移入, 0 移出)。'

编辑和删除功能:

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {

// Delete the row from the data source
var deleteRow = indexPath.row

indexPathforDelete = indexPath

let entityDescription = NSEntityDescription.entityForName("People", inManagedObjectContext: managedObjectContext!)
let request = NSFetchRequest()
request.entity = entityDescription

var error: NSError?

var objects = managedObjectContext?.executeFetchRequest(request, error: &error)

if let results = objects {

let personToDelete = results[deleteRow] as! NSManagedObject
let firstName = personToDelete.valueForKey("firstName") as! String
let lastName = personToDelete.valueForKey("lastName") as! String

var message = "Are you sure you would like to delete \(firstName) \(lastName)?\nThis will permanentaly remove all records of "

if(personToDelete.valueForKey("gender") as! String == "Male"){

message = "\(message)him."

}

else{

println(personToDelete.valueForKey("gender") as! String)

message = "\(message)her."

}

var deleteAlert : UIAlertView = UIAlertView(title: "Delete \(firstName) \(lastName)", message: message, delegate: self, cancelButtonTitle: "Cancel")

deleteAlert.addButtonWithTitle("Delete")

deleteAlert.show()

}

save()

} 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

}
}

AlertView 响应函数:

func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int){

if(buttonIndex == 1){
managedObjectContext?.deleteObject(personToDelete)
tableView.deleteRowsAtIndexPaths([indexPathforDelete], withRowAnimation: .Fade)
save()
}

setEditing(false, animated: true)
self.navigationItem.leftBarButtonItem = nil

}

tableView行数函数:

var personToDelete = NSManagedObject()
var indexPathforDelete = NSIndexPath()

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.

let entityDescription = NSEntityDescription.entityForName("People", inManagedObjectContext: managedObjectContext!)
let request = NSFetchRequest()
request.entity = entityDescription

var error: NSError?

var objects = managedObjectContext?.executeFetchRequest(request, error: &error)

let results = objects

println("Results Count: \(results!.count)")

return results!.count

}

最佳答案

认为 问题是您有两个名为 propertyToDelete 的变量:一个您声明并使用空白 NSManagedObject 初始化的属性:

        var personToDelete = NSManagedObject()

以及您在 commitEditingStyle 函数中声明的局部变量:

        let personToDelete = results[deleteRow] as! NSManagedObject

您将结果数组中的对象分配给这个局部变量。但是这个局部变量在函数完成时被销毁,并且 AlertView 操作正在删除 property 指向的对象。 (我犹豫的原因是我希望您的上下文在尝试删除从未注册过的对象时抛出错误)。请注意,相比之下,您只有一个名为 indexPathforDelete 的变量。这在 AlertView 操作运行时保存正确的值,因此 tableView 删除了正确的行。这就是您收到错误的原因:它删除了一行,但随后发现(因为没有删除任何对象)它仍然具有与之前相同的行数。

直接的解决方案是在函数中使用属性,而不是局部变量:只需删除 let:

        personToDelete = results[deleteRow] as! NSManagedObject

但我还建议重新考虑您的方法:您正在重复相同的提取。如果所有的数据源方法都做同样的事情,那么在第一次构建 TableView 时,每当一个单元格滚动到 View 中,每当一个单元格被点击时,它都会重复多次。这将在性能方面付出高昂的代价。相反,您应该进行一次提取(也许在 viewDidLoad 中),将结果存储在数组属性中,并将其用于 TableView 数据源方法。或者,也许最好使用 NSFetchedResultsController:它非常高效,并且有用于在添加或删除对象时更新 TableView 的样板代码。

关于swift - NSInternalInconsistencyException : Invalid Update using tableview CoreData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32278364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com