我今天开始学习CoreData,我在Ray Wenderlich(https://www.raywenderlich.com/145809/getting-started-core-data-tutorial)上学习了很好的教程
完成的项目以表格视图结束,填充了用户通过导航栏中的“添加”按钮输入的标签。
我也继续使用删除功能,因为那不在教程中:
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if editingStyle == .delete
{
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
tableView.beginUpdates()
companies.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
appDelegate.saveContext()
}
}
然而,当我导航到另一个视图控制器然后返回时,已删除的对象再次出现。我将公司初始化为文件顶部的托管对象:
var companies = [NSManagedObject]()
我想
companies.remove(at: indexPath.row)
接着是
appDelegate.saveContext()
删除函数中的会从数据源中删除该对象,但就像我说它仍然在那里。
如何删除对象,以便当我离开页面并返回时,它仍然被删除,但如果我重新启动应用程序,它会回来?
编辑(适用于我的代码)
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
let company = companies[indexPath.row]
if editingStyle == .delete {
managedContext.delete(company)
do {
try managedContext.save()
} catch let error as NSError {
print("Error While Deleting Note: \(error.userInfo)")
}
}
// Fetch new data/reload table
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: companyEntity)
do {
companies = try managedContext.fetch(fetchRequest) as! [NSManagedObject]
} catch let error as NSError {
print("Error While Fetching Data From DB: \(error.userInfo)")
}
tableView.reloadData()
}
上面的代码可以使对象保持删除状态,如果我离开视图然后返回,但是如果我重新启动应用程序,它们仍然会被删除 - 如果应用程序重新启动,我希望删除已删除的项目。
答案 0 :(得分:3)
在我看来,你根本不是从CoreData删除对象。
companies.remove(at: indexPath.row)
- 这里只需从获取的数据数组中删除对象
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if editingStyle == .delete {
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
//remove object from core data
let context:NSManagedObjectContext = appDelegate.managedObjectContext!
context.deleteObject(companies[indexPath.row] as NSManagedObject)
context.save(nil)
//update UI methods
tableView.beginUpdates()
companies.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
appDelegate.saveContext()
}
}
答案 1 :(得分:1)
然而,当我导航到另一个视图控制器然后返回时,已删除的对象再次出现
当然,因为你没有采取任何措施来改变底层数据模型。
如果我离开视图然后返回,对象会保持删除状态,但是如果我重新启动应用程序,它们仍会被删除 - 如果应用程序重新启动,我希望删除已删除的项目
对不起,你为什么要这样?删除项目意味着删除它!也就是说,这意味着它将从基础数据模型中删除,这是核心数据数据库。你为什么要把死人复活?
在我看来,你真正的问题是核心数据是一个完全不合适的底层数据模型,用于你真正想要做的事情(不管它是什么)。核心数据不是初学者技术。我建议你放弃使用它。
答案 2 :(得分:0)
我认为您的第一个代码更接近您想要的内容。
最简单的行为是仅提取 ,从Core Data中删除并从表视图中删除以更新UI。这就是它,没有重新获取,没有重新加载。
OR
从核心数据中获取,删除,重新获取并重新加载表以查看用户界面中的更改。选一个!
如果你有一个数组作为中间数,你当然应该删除它。
现在,您不需要总是拥有一个数组(关于获取结果控制器的研究),您可以直接使用Core Data,但幸运的是,这正是您在这种情况下所需要的。
我的建议:获取核心数据仅一次以获取初始数据,将所有内容放入数组,使用数组进行操作,使其成为表的数据源并删除项中的数据数组和表格。因此,您的核心数据不会被删除,只会为您的工作阵列提供初始值。
对于插页,我想你想保留它们。如果您愿意,可以将它们保存到数组,表格和核心数据中。
最后一件事,你是在第一行代码中守护AppDelegate。如果您的应用程序正在运行,您肯定有AppDelegate,没有它,您的应用程序就无法运行,它会控制您的应用程序生命周期。你可能在遇到困境时遇到问题(很少但很可能)。保护上下文:
guard let context = (UIApplication.shared.delegate as? AppDelegate)?.managedObjectContext else {
return
}
希望它有所帮助。