Ios 使用Swift 3中的CoreData从表视图中删除对象

Ios 使用Swift 3中的CoreData从表视图中删除对象,ios,swift,core-data,Ios,Swift,Core Data,今天我开始学习CoreData,我学习了Ray Wenderlich() 完成的项目以表格视图结束,表格视图中填充了用户通过导航栏中的“添加”按钮输入的标签 我还加入了删除功能,因为教程中没有该功能: override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { if editingSt

今天我开始学习CoreData,我学习了Ray Wenderlich()

完成的项目以表格视图结束,表格视图中填充了用户通过导航栏中的“添加”按钮输入的标签

我还加入了删除功能,因为教程中没有该功能:

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()
在delete函数中,将从数据源中删除对象,但正如我所说,它仍然存在

我怎样才能删除该对象,这样当我离开页面返回时,它仍然被删除,但如果我重新启动应用程序,它将返回

编辑(对我有用的代码)

重写func tableView(tableView:UITableView,commit editingStyle:UITableViewCellEditingStyle,forRowAt indexPath:indexPath)
{
let company=companys[indexPath.row]
如果editingStyle==.delete{
managedContext.delete(公司)
做{
请尝试managedContext.save()
}将let错误捕获为NSError{
打印(“删除注释时出错:\(Error.userInfo)”)
}
}
//获取新数据/重新加载表
let fetchRequest=NSFetchRequest(entityName:companyEntity)
做{
companys=尝试managedContext.fetch(fetchRequest)as![NSManagedObject]
}将let错误捕获为NSError{
打印(“从数据库提取数据时出错:\(Error.userInfo)”)
}
tableView.reloadData()
}

上述代码的工作原理是,如果我离开视图,对象将保持删除状态,然后返回,但是如果我重新启动应用程序,它们仍然会被删除-如果重新启动应用程序,我希望删除的项目返回。

在我看来,您根本不是从CoreData中删除对象

companys.remove(位于: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()
    }
}

在我看来,您根本不是从CoreData中删除对象

companys.remove(位于: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()
    }
}
但是,当我导航到另一个视图控制器然后返回时,删除的对象又出现了

当然,因为您没有更改参考底图数据模型

如果我离开视图,对象将保持删除状态,然后返回,但是如果我重新启动应用程序,它们仍将被删除-如果重新启动应用程序,我希望删除的项目返回

对不起,你为什么要那样?删除项目意味着删除它!也就是说,这意味着它将从底层数据模型(即核心数据数据库)中删除。你为什么要让死人复活

在我看来,您真正的问题在于核心数据对于您真正想要做的事情(无论它是什么)是完全不合适的底层数据模型。核心数据不是一项初学者技术。我建议你放弃使用它

但是,当我导航到另一个视图控制器然后返回时,删除的对象又出现了

当然,因为您没有更改参考底图数据模型

如果我离开视图,对象将保持删除状态,然后返回,但是如果我重新启动应用程序,它们仍将被删除-如果重新启动应用程序,我希望删除的项目返回

对不起,你为什么要那样?删除项目意味着删除它!也就是说,这意味着它将从底层数据模型(即核心数据数据库)中删除。你为什么要让死人复活


在我看来,您真正的问题在于核心数据对于您真正想要做的事情(无论它是什么)是完全不合适的底层数据模型。核心数据不是一项初学者技术。我建议您放弃使用它。

我认为您的第一个代码更接近您想要的

最简单的行为是只获取一次,从核心数据中删除,并从表视图中删除,以更新UI。就这样,没有重新蚀刻,没有重新加载

从核心数据中提取、删除、重新提取和重新加载表,以查看用户界面中的更改。挑一个

如果有一个数组作为中间数组,当然也应该删除其中的一个

现在,您不需要总是拥有一个数组,(研究获取的结果控制器),您可以直接使用核心数据,但幸运的是,这正是您在本例中所需要的

我的建议是:只获取一次核心数据,以获取初始数据,将所有内容放入数组中,使用数组进行处理,将其作为表的数据源,并仅删除数组和表中的项。因此,您的核心数据不会被删除,它只会为您的工作数组提供初始值

对于插页,我想您应该保留它们。如果需要,将它们保存到阵列、表和核心数据中

最后一件事是,在代码的第一行中保护AppDelegate。如果你的应用正在运行,你肯定有一个AppDelegate,没有它你的应用无法运行,它控制着你的应用的生命周期。你可能会遇到难以理解的问题(虽然很少,但可能)。保护上下文:

guard let context = (UIApplication.shared.delegate as? AppDelegate)?.managedObjectContext else { 
     return
}

希望有帮助。

我认为您的第一个代码更接近您想要的

最简单的行为是只获取一次,从核心数据中删除,并从表视图中删除,以更新UI。就这样,没有重新蚀刻,没有重新加载

从核心数据中提取、删除、重新提取和重新加载表,以查看用户界面中的更改。挑一个

如果有一个数组作为中间数组,当然也应该删除其中的一个

现在,您不需要总是拥有一个数组,(研究获取的结果控制器),您可以直接使用核心Dat