CoreData如何将项目添加到与实体相关的NSSet

Posted

技术标签:

【中文标题】CoreData如何将项目添加到与实体相关的NSSet【英文标题】:CoreData how to add items to a NSSet which is related to an entity 【发布时间】:2020-12-09 14:37:06 【问题描述】:

在我的项目中,我创建了两个实体:ContainerItems。两者之间是一对多的关系。在Container 中,我调用了关系项并将其设置为“To Many”,因为我希望每个容器中有很多项。在Items 中,我调用了关系容器并将其设置为“To One”,因为每个项目都必须与一个且只有一个容器相关联。

除此之外,在我的项目中,我有一个表格视图,我可以在其中添加新容器,当我按下一个单元格时,我可以看到它的项目。创建容器的代码很好。当我尝试创建项目时出现问题:它们已成功创建但它们出现在每个容器中。

在下面的部分中,我将发布对象,如何保存容器以及如何保存项目:

对象:
extension Container 

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Container> 
        return NSFetchRequest<Container>(entityName: "Container")
    

    @NSManaged public var name: String?
    @NSManaged public var index: Int64
    @NSManaged public var items: NSSet?



extension Items 

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Items> 
        return NSFetchRequest<Items>(entityName: "Items")
    

    @NSManaged public var text: String?
    @NSManaged public var image: UIImage?
    @NSManaged public var index: Int64
    @NSManaged public var container: Container?


创建容器:
let containerEntity = NSEntityDescription.entity(forEntityName: "Container", in: managedContext)!
        
        let items: NSSet = []
        
        let container = NSManagedObject(entity: containerEntity, insertInto: managedContext) as! Container
        
        ///Count is just an int variable
        container.setValue("Name", forKeyPath: "name")
        container.setValue(count, forKeyPath: "index")
        container.setValue(items, forKey: "items")
        
        do 
            try managedContext.save()

         catch let error as NSError 
            print("Could not save. \(error), \(error.userInfo)")
        
创建项目:
  let itemEntity = NSEntityDescription.entity(forEntityName: "Items", in: managedContext)!
        
        let items = NSManagedObject(entity: itemEntity, insertInto: managedContext) as! Items
 
        items.setValue("item", forKeyPath: "text")
        items.setValue(count, forKeyPath: "index")
     
        
        do 
            try managedContext.save()

         catch let error as NSError 
            print("Could not save. \(error), \(error.userInfo)")
        
        

无论如何,我认为我应该编辑容器实体,而不是创建项目实体,然后将其添加到项目中。为此,我尝试了这个,但我觉得我错过了一些东西,因为这个东西崩溃了。

let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "container")
       
       do 
           let test = try managedContext.fetch(fetchRequest)
           
           let objectUpdate = test[containerIndex] as! NSManagedObject
           
           objectUpdate.setValue("item", forKey: "text")
           objectUpdate.setValue(count, forKey: "index")
           
           do
               try managedContext.save()
            catch 
               print(error)
           
          
       
       catch 
           print(error)
       

那么如何将项目添加到特定容器中?

另外,如果我的两个实体属性被称为索引可以吗?

【问题讨论】:

【参考方案1】:

如果设置正确,应该有一个addToItems()

anyContainerObject.addToItems(value: Items)

【讨论】:

谢谢!但是我该怎么称呼它呢?我的意思是,我必须选择一个特定的容器,所以我假设我应该继续我发布的第二次尝试,但是我是否必须将对象值转换为 Container 而不是 NSManagedObject?在价值之后,我如何创建要添加的项目?我是否使用我发布的第一种方式并传递我称为项目的常量?再次感谢您的回答 您应该查看 CoreData 编程指南developer.apple.com/library/archive/documentation/Cocoa/… 和 Xcode 在您创建新项目时提供的示例代码。您可以像创建Container 一样创建Items 对象,然后在没有您的用例的一些实际示例代码的情况下创建addToItems(),我无法为您提供更具体的信息。你必须有一个Container 而不是NSManagedObject,你可以通过 FetchRequest 自动获得它。尝试一些教程。【参考方案2】:

只要您在核心数据模型中正确设置了反向关系,最简单的方法就是将相关的Container 实例分配给新的Itemcontainer 属性。核心数据将负责为您更新ContainerItems 集。

let itemEntity = NSEntityDescription.entity(forEntityName: "Items", in: managedContext)!
        
let items = NSManagedObject(entity: itemEntity, insertInto: managedContext) as! Items
 
items.setValue("item", forKeyPath: "text")
items.setValue(count, forKeyPath: "index")
items.setValue(container, forKeyPath: "container")

do 
    try managedContext.save()
 catch let error as NSError 
    print("Could not save. \(error), \(error.userInfo)")

如果您使用为您的核心数据实体自动创建的对象,您的代码将更简单、更易于维护

        
let items = Item(context:managedObjectContext)
 
items.text = item
items.count = index
items.container = container

do 
    try managedContext.save()
 catch let error as NSError 
    print("Could not save. \(error), \(error.userInfo)")

【讨论】:

以上是关于CoreData如何将项目添加到与实体相关的NSSet的主要内容,如果未能解决你的问题,请参考以下文章

如何使用CoreData获取相关实体的对象?

Swift - 为相关的 CoreData 实体赋值

CoreData:添加时的两级 fetchRequest

错误:将实体添加到 CoreData 时“在实体中找不到键路径索引”

CoreData 向实体行添加新关系

使用 Objective-C 将 CoreData 添加到现有项目中