在 NSBatchDeleteRequest 之后使用核心数据

Posted

技术标签:

【中文标题】在 NSBatchDeleteRequest 之后使用核心数据【英文标题】:Using Core Data After NSBatchDeleteRequest 【发布时间】:2017-05-17 08:16:37 【问题描述】:

在我的应用程序中,当我从 Web 服务刷新实体的内容时,我会删除我的核心数据中的所有记录并插入所有新记录。然而,很多时候记录并没有从上下文中删除,即使我再次调用上下文。所以当我保存时,旧的仍然存在,我最终只是堆叠在现有的之上,得到了很多重复。我怎样才能完全清除上下文,这样我就不用担心重复了?

    var appDelegate = UIApplication.shared.delegate as! AppDelegate
    var context = appDelegate.persistentContainer.viewContext
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "V_ServiceDetails")

    // Clear all
    let request = NSBatchDeleteRequest(fetchRequest: fetchRequest)

    do 
        let result = try context.execute(request)
     catch 

    appDelegate = UIApplication.shared.delegate as! AppDelegate
    context = appDelegate.persistentContainer.viewContext

    // Add new ones
    for svc in self.svcs 
        let result = NSEntityDescription.insertNewObject(forEntityName: "V_ServiceDetails", into: context)

        result.setValue(svc.Car_VIN, forKey: "car_VIN")
        result.setValue(svc.Cust_Veh_ID, forKey: "cust_Veh_ID")

        do  try context.save()  catch 
    

【问题讨论】:

删除上下文中的项目后。你可以尝试保存上下文context.save() @TheAppMentor 我已将其更新为:do let result = try context.execute(request) try context.save() catch ,但没有任何区别。 【参考方案1】:

来自Apple docs on batch delete,它说删除是直接在SQL 级别完成的。删除在内存中的对象中未反映,因此您需要在删除后更新您的应用程序。请参阅链接页面上的执行后更新您的应用程序部分。

【讨论】:

【参考方案2】:

试试下面这个功能:

func deleteAll() 

    // Managed Object Context
    let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    // Save the changes of the Managed Object Context before executing the Batch Delete Request
    if managedObjectContext.hasChanges 
        do 
            try managedObjectContext.save()
         catch 
            // Error
        
    

    // Craete a Fetch Request
    let fetchRequest: NSFetchRequest<ManagedObject> = ManagedObject.fetchRequest()

    // Initiliaze the Batch Delete Request
    let batchDeleteRequest = NSBatchDeleteRequest.init(fetchRequest: fetchRequest as! NSFetchRequest<NSFetchRequestResult>)

    // Configure the Batch Delete Request
    batchDeleteRequest.resultType = .resultTypeCount

    do 

        // Execute the Batch Delete Request
        try managedObjectContext.execute(batchDeleteRequest)

        // Reset the Managed Object Context
        managedObjectContext.reset()

        // try self.fetchedResultsController.performFetch()
        // If you have a Table View? Use this function
        // self.tableView.reloadData()

     catch 
        // Error
    

【讨论】:

【参考方案3】:

这对我有用。

var e = 1
    
    while e <= self.items!.count 
        
        self.context.delete(self.items![e - 1])
        
        // Save the data
        do 
            try self.context.save()
            
        
        catch 
            
            
        
        
        e = e + 1
        
        
    

【讨论】:

以上是关于在 NSBatchDeleteRequest 之后使用核心数据的主要内容,如果未能解决你的问题,请参考以下文章

UI 在执行 NSBatchDeleteRequest 时冻结

NSBatchDeleteRequest 留下不好的关系

如何设置 NSBatchDeleteRequest 的 NSBatchDeleteResult 类型?

核心数据 NSBatchDeleteRequest 似乎将对象留在上下文中

如何让 NSBatchDeleteRequest 删除并允许您再次添加回对象

为啥在 setContentView() 之后 UI 不加载,而是在 onCreate() 执行之后加载?