【问题标题】:Why do we need to call context.delete to delete an item from NSManagedObject array?为什么我们需要调用 context.delete 从 NSManagedObject 数组中删除一个项目?
【发布时间】:2022-01-01 23:13:49
【问题描述】:

假设我有;

var itemArray = [Item]()

并且 Item 是一个 NSManagedObject。 Item 有两个属性“Title”:String 和“Done”:Boolean。这是我的数据模型的图片。

//  Item+CoreDataClass.swift

//  This file was automatically generated and should not be edited.
//

 import Foundation
 import CoreData

 public class Item: NSManagedObject {

 }

当我更改 Done 的值并调用 context.save 时,它​​会自动反映到 Persistent Container。但是,当我通过说从数组中删除一个元素时,

itemArray.remove(at: someindex)

并调用 context.save。该项目不会从 Persistent Container 中删除。只有当我打电话时,

context.delete(itemArray[someindex])

然后该项目真正从存储中删除。

那么为什么只从 itemArray 中删除并保存上下文是不够的,尽管更改属性的值和保存上下文对于在 Core Data 上成功进行 CRUD 操作就足够了?

【问题讨论】:

  • 为什么 Core Data 会知道你的变量和属性?

标签: ios swift core-data


【解决方案1】:

当您更改 Item 对象的属性时,Core Data(实际上是 NSManagedObjectContext)会检测到,因为 Item 属于 NSManagedObjectContext 并且该项目被标记为脏。但是您的数组与 NSManagedObjectContext 没有任何联系,因此您对其所做的任何更改都不会被 NSManagedObjectContext 检测到,这就是为什么您需要明确告诉它您要删除从数组中删除的项目。

另一种看待它的方式是,您在 Core Data 模型中创建/定义的任何内容都为 NSManagedObjectContext 所知,但在 swift 代码之外创建的任何内容都是未知的。如果您开始处理实体之间的多对多关系,您将看到从多对多集合中添加或删除对象将由 NSManagedObjectContext 以您期望的数组方式直接处理。

【讨论】:

    【解决方案2】:

    数组var itemArray = [Item]() 与底层数据库没有直接关系。因此,从该数组中删除项目不会影响 Core Data 数据库。

    要在 Core Data 数据库中创建、保存或删除 NSManagedObject 实例,您需要调用有效 NSManagedObjectContext 的相关函数。

    【讨论】:

      【解决方案3】:

      CoreData 上的任何操作都应该通过NSManagedObjectContext 完成,因为它是访问或更新数据库中任何实体的暂存器。因此,在您的情况下,在删除 Item 实体时,您应该通过上下文执行此操作,以便反映在数据库中。

      var itemArray = [Item]()
      let context = //get your context
      let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Item")
      let predicate = NSPredicate(format: " (primaryKey == %@) ", "your_primary_key")
      fetchRequest.predicate = predicate
      itemArray = try! context.fetch(fetchRequest)
      for i in 0 ..< itemArray.count where i < itemArray.count-1 {
          context.delete(itemArray[i])
      }
      
      do {
          try context.save()
      } catch {
          // print the error
      }
      

      【讨论】:

      • 我想知道为什么更新调用直接反映在 CoreData 基础上。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 2016-05-08
      • 1970-01-01
      相关资源
      最近更新 更多