Core data 如何防止核心数据Swift 3中的删除规则拒绝出现错误
如何防止删除规则中出现错误?我有一个警报,要求用户删除一条记录,但检查是否可以删除它首先发生在核心数据堆栈中的save方法中。我试着用以下方法抓住它:Core data 如何防止核心数据Swift 3中的删除规则拒绝出现错误,core-data,swift3,Core Data,Swift3,如何防止删除规则中出现错误?我有一个警报,要求用户删除一条记录,但检查是否可以删除它首先发生在核心数据堆栈中的save方法中。我试着用以下方法抓住它: if (self?.categoryToEdit.toMyplace == nil){ let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nich
if (self?.categoryToEdit.toMyplace == nil){
let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nSie ist ", preferredStyle: .actionSheet)
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
self?.attemptFetch()
self?.tableView.reloadData()
return
})
alertController.addAction(cancelButton)
self?.present(alertController, animated: false, completion: nil)
}else{
self?.displayActionSheet(indexPath: indexPath as NSIndexPath)
}
因此,我从编译器中得到一个错误:致命错误:在展开可选值时意外发现nil
我怎样才能解决它
提前感谢
编辑
谢谢大家!!
这里是完整的代码。
它在tableView操作中启动,并转发到处理警报的单独功能。此函数中未注释的部分实际上不起作用。当它处理错误时,我首先得到一个警报。
如果记录没有从tableView中消失,并在工作数组的索引中留下香,这将不会是一个大问题。
这个问题一直存在,直到应用程序重新启动,才有可能获得未删除的记录。我尝试新的fetch请求并重新加载表日期,但它会一直保持到新的开始
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let edit = UITableViewRowAction(style: .normal, title: "Ändern") { [weak self] action, index in
self?.editMode = true
let cell = tableView.cellForRow(at: indexPath) as! CategoryTVCell
self?.configureCell(cell: cell, indexPath: indexPath)
context.performAndWait{
if let obj = self?.controller.fetchedObjects , obj.count > 0 {
self?.categoryToEdit = obj[indexPath.row]
self?.categoryToEditName = self?.categoryToEdit.name!
}
}
self?.showAlertWithText()
self?.showAlertWithText()
tableView.isEditing = false
}
let delete = UITableViewRowAction(style: .normal, title: "Löschen") { [weak self] action, index in
self?.displayActionSheet(indexPath: indexPath as NSIndexPath)
}
edit.backgroundColor = UIColor(colorLiteralRed: 179.0/255.0, green: 179.0/255.0, blue: 179.0/255.0, alpha: 1)
delete.backgroundColor = myRedAlertColor
return [delete, edit]
}
private func displayActionSheet(indexPath: NSIndexPath)
{ let categoryName = categoryArray[indexPath.row]
let alertController = UIAlertController(title: "Kategorie löschen", message: "Soll die Kategorie " + categoryName + " gelöscht werden?\r\nDie Kategorie kann nur gelöscht werden, wenn kein myPlace damit verbunden ist!", preferredStyle: .actionSheet)
let deleteCategory = UIAlertAction(title: "Löschen", style: .destructive, handler: { [weak self](action) -> Void in
self?.tableView.isEditing = false
//if (self?.categoryToEdit.toMyplace == nil)/*((self?.myPlace?.toCateogry == nil))*/{
context.delete((self?.controller.fetchedObjects?[indexPath.row])!)
self?.categoryArray.remove(at: indexPath.row)
self?.attemptFetch()
self?.tableView.reloadData()
//}else{
/*let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nSie ist ", preferredStyle: .actionSheet)
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
self?.attemptFetch()
self?.tableView.reloadData()
})
alertController.addAction(cancelButton)
self?.present(alertController, animated: false, completion: nil)*/
//}
do{
try context.save()
}catch{
let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nAlle myPlaces verlieren sonst diese Zuordnung!", preferredStyle: .actionSheet)
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
self?.attemptFetch()
self?.tableView.reloadData()
})
alertController.addAction(cancelButton)
self?.present(alertController, animated: false, completion: nil)
}
})
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
})
alertController.addAction(deleteCategory)
alertController.addAction(cancelButton)
alertController.view.tintColor = .orange //UIColor(red: 0, green: 0, blue: 51)
//self.navigationController!.present(alertController, animated: true, completion: nil)
present(alertController, animated: false, completion: nil)
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let edit = UITableViewRowAction(style: .normal, title: "Ändern") { [weak self] action, index in
self?.editMode = true
let cell = tableView.cellForRow(at: indexPath) as! CategoryTVCell
self?.configureCell(cell: cell, indexPath: indexPath)
context.performAndWait{
if let obj = self?.controller.fetchedObjects , obj.count > 0 {
self?.categoryToEdit = obj[indexPath.row]
self?.categoryToEditName = self?.categoryToEdit.name!
}
}
self?.showAlertWithText()
self?.showAlertWithText()
tableView.isEditing = false
}
let delete = UITableViewRowAction(style: .normal, title: "Löschen") { [weak self] action, index in
self?.displayActionSheet(indexPath: indexPath as NSIndexPath)
}
edit.backgroundColor = UIColor(colorLiteralRed: 179.0/255.0, green: 179.0/255.0, blue: 179.0/255.0, alpha: 1)
delete.backgroundColor = myRedAlertColor
return [delete, edit]
}
private func displayActionSheet(indexPath: NSIndexPath)
{ let categoryName = categoryArray[indexPath.row]
let alertController = UIAlertController(title: "Kategorie löschen", message: "Soll die Kategorie " + categoryName + " gelöscht werden?\r\nDie Kategorie kann nur gelöscht werden, wenn kein myPlace damit verbunden ist!", preferredStyle: .actionSheet)
let deleteCategory = UIAlertAction(title: "Löschen", style: .destructive, handler: { [weak self](action) -> Void in
self?.tableView.isEditing = false
//if (self?.categoryToEdit.toMyplace == nil)/*((self?.myPlace?.toCateogry == nil))*/{
context.delete((self?.controller.fetchedObjects?[indexPath.row])!)
self?.categoryArray.remove(at: indexPath.row)
self?.attemptFetch()
self?.tableView.reloadData()
//}else{
/*let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nSie ist ", preferredStyle: .actionSheet)
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
self?.attemptFetch()
self?.tableView.reloadData()
})
alertController.addAction(cancelButton)
self?.present(alertController, animated: false, completion: nil)*/
//}
do{
try context.save()
}catch{
let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nAlle myPlaces verlieren sonst diese Zuordnung!", preferredStyle: .actionSheet)
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
self?.attemptFetch()
self?.tableView.reloadData()
})
alertController.addAction(cancelButton)
self?.present(alertController, animated: false, completion: nil)
}
})
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
})
alertController.addAction(deleteCategory)
alertController.addAction(cancelButton)
alertController.view.tintColor = .orange //UIColor(red: 0, green: 0, blue: 51)
//self.navigationController!.present(alertController, animated: true, completion: nil)
present(alertController, animated: false, completion: nil)
}
谢谢大家!!
这里是完整的代码。
它在tableView操作中启动,并转发到处理警报的单独功能。此函数中未注释的部分实际上不起作用。当它处理错误时,我首先得到一个警报。
如果记录没有从tableView中消失,并在工作数组的索引中留下香,这将不会是一个大问题。
这个问题一直存在,直到应用程序重新启动,才有可能获得未删除的记录。我尝试新的fetch请求并重新加载表日期,但它会一直保持到新的开始
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let edit = UITableViewRowAction(style: .normal, title: "Ändern") { [weak self] action, index in
self?.editMode = true
let cell = tableView.cellForRow(at: indexPath) as! CategoryTVCell
self?.configureCell(cell: cell, indexPath: indexPath)
context.performAndWait{
if let obj = self?.controller.fetchedObjects , obj.count > 0 {
self?.categoryToEdit = obj[indexPath.row]
self?.categoryToEditName = self?.categoryToEdit.name!
}
}
self?.showAlertWithText()
self?.showAlertWithText()
tableView.isEditing = false
}
let delete = UITableViewRowAction(style: .normal, title: "Löschen") { [weak self] action, index in
self?.displayActionSheet(indexPath: indexPath as NSIndexPath)
}
edit.backgroundColor = UIColor(colorLiteralRed: 179.0/255.0, green: 179.0/255.0, blue: 179.0/255.0, alpha: 1)
delete.backgroundColor = myRedAlertColor
return [delete, edit]
}
private func displayActionSheet(indexPath: NSIndexPath)
{ let categoryName = categoryArray[indexPath.row]
let alertController = UIAlertController(title: "Kategorie löschen", message: "Soll die Kategorie " + categoryName + " gelöscht werden?\r\nDie Kategorie kann nur gelöscht werden, wenn kein myPlace damit verbunden ist!", preferredStyle: .actionSheet)
let deleteCategory = UIAlertAction(title: "Löschen", style: .destructive, handler: { [weak self](action) -> Void in
self?.tableView.isEditing = false
//if (self?.categoryToEdit.toMyplace == nil)/*((self?.myPlace?.toCateogry == nil))*/{
context.delete((self?.controller.fetchedObjects?[indexPath.row])!)
self?.categoryArray.remove(at: indexPath.row)
self?.attemptFetch()
self?.tableView.reloadData()
//}else{
/*let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nSie ist ", preferredStyle: .actionSheet)
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
self?.attemptFetch()
self?.tableView.reloadData()
})
alertController.addAction(cancelButton)
self?.present(alertController, animated: false, completion: nil)*/
//}
do{
try context.save()
}catch{
let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nAlle myPlaces verlieren sonst diese Zuordnung!", preferredStyle: .actionSheet)
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
self?.attemptFetch()
self?.tableView.reloadData()
})
alertController.addAction(cancelButton)
self?.present(alertController, animated: false, completion: nil)
}
})
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
})
alertController.addAction(deleteCategory)
alertController.addAction(cancelButton)
alertController.view.tintColor = .orange //UIColor(red: 0, green: 0, blue: 51)
//self.navigationController!.present(alertController, animated: true, completion: nil)
present(alertController, animated: false, completion: nil)
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let edit = UITableViewRowAction(style: .normal, title: "Ändern") { [weak self] action, index in
self?.editMode = true
let cell = tableView.cellForRow(at: indexPath) as! CategoryTVCell
self?.configureCell(cell: cell, indexPath: indexPath)
context.performAndWait{
if let obj = self?.controller.fetchedObjects , obj.count > 0 {
self?.categoryToEdit = obj[indexPath.row]
self?.categoryToEditName = self?.categoryToEdit.name!
}
}
self?.showAlertWithText()
self?.showAlertWithText()
tableView.isEditing = false
}
let delete = UITableViewRowAction(style: .normal, title: "Löschen") { [weak self] action, index in
self?.displayActionSheet(indexPath: indexPath as NSIndexPath)
}
edit.backgroundColor = UIColor(colorLiteralRed: 179.0/255.0, green: 179.0/255.0, blue: 179.0/255.0, alpha: 1)
delete.backgroundColor = myRedAlertColor
return [delete, edit]
}
private func displayActionSheet(indexPath: NSIndexPath)
{ let categoryName = categoryArray[indexPath.row]
let alertController = UIAlertController(title: "Kategorie löschen", message: "Soll die Kategorie " + categoryName + " gelöscht werden?\r\nDie Kategorie kann nur gelöscht werden, wenn kein myPlace damit verbunden ist!", preferredStyle: .actionSheet)
let deleteCategory = UIAlertAction(title: "Löschen", style: .destructive, handler: { [weak self](action) -> Void in
self?.tableView.isEditing = false
//if (self?.categoryToEdit.toMyplace == nil)/*((self?.myPlace?.toCateogry == nil))*/{
context.delete((self?.controller.fetchedObjects?[indexPath.row])!)
self?.categoryArray.remove(at: indexPath.row)
self?.attemptFetch()
self?.tableView.reloadData()
//}else{
/*let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nSie ist ", preferredStyle: .actionSheet)
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
self?.attemptFetch()
self?.tableView.reloadData()
})
alertController.addAction(cancelButton)
self?.present(alertController, animated: false, completion: nil)*/
//}
do{
try context.save()
}catch{
let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nAlle myPlaces verlieren sonst diese Zuordnung!", preferredStyle: .actionSheet)
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
self?.attemptFetch()
self?.tableView.reloadData()
})
alertController.addAction(cancelButton)
self?.present(alertController, animated: false, completion: nil)
}
})
let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
})
alertController.addAction(deleteCategory)
alertController.addAction(cancelButton)
alertController.view.tintColor = .orange //UIColor(red: 0, green: 0, blue: 51)
//self.navigationController!.present(alertController, animated: true, completion: nil)
present(alertController, animated: false, completion: nil)
}
以下是解决方案:
let delete = UITableViewRowAction(style: .normal, title: "Löschen")
{
[weak self] action, index in
do{
try self?.controller.fetchedObjects?[indexPath.row].validateForDelete()
self?.displayActionSheet(indexPath: indexPath as NSIndexPath)
}catch{
let categoryName = self?.categoryArray[indexPath.row]
let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName! + " kann nicht gelöscht werden!\r\nSie wird bereits verwendet!", preferredStyle: .actionSheet)
let cancelButton = UIAlertAction(title: "Abbrechen",
style: .cancel, handler: {
[weak self](action) -> Void in
self?.tableView.setEditing(false, animated: true)
self?.attemptFetch()
self?.tableView.reloadData()
})
alertController.addAction(cancelButton)
self?.present(alertController, animated: false, completion: nil)
}
}
它只是一个函数。validateForDelete()请您共享执行删除操作的代码。还有,你的核心数据栈是什么样子的?请删除这篇文章,因为这是有问题的更新,我已经将这个更新合并到了问题中。