【问题标题】:How to insert new data to entity in Swift?如何在 Swift 中向实体插入新数据?
【发布时间】:2016-06-19 09:36:19
【问题描述】:

在之前的 Swift 中,我可以使用这样的代码将新数据添加到我的数据模型中的“TestEntity”中。

NSManagedObject 是为我的“TestEntity”创建的,我可以使用“点”语法设置它的属性

最后,我会保存上下文

let entity=NSEntityDescription.insertNewObject(forEntityName: "TestEntity", into: context) as! TestEntity
entity.testAttribute="test value"
context.save()

此代码在 Swift 3 中不起作用。当我运行它时,我收到以下运行时错误:

无法转换“NSManagedObject_TestEntity_”类型的值 (0x175306b0)到“testCoreData.TestEntity”(0xd6bb8)。 2016-06-19 11:07:52.305195 testCoreData [689:264453] 无法转换类型的值 'NSManagedObject_TestEntity_' (0x175306b0) 到 'testCoreData.TestEntity' (0xd6bb8)

谁能解释在 Swift 3 中应该如何做到这一点?

问题的第二部分是如何再次访问数据。以下代码以错误结尾:

致命错误:NSArray 元素未能匹配 Swift 数组元素类型

let fr:NSFetchRequest<TestEntity>=TestEntity.fetchRequest()
        
do {
   let searchResults=try context.fetch(fr)
   if let results=searchResults {
      for result in results {
         print("testAtt = \(result.testAtt)")
      }
   }
} catch {
            
}

【问题讨论】:

    标签: swift core-data swift3 nsmanagedobject nsentitydescription


    【解决方案1】:

    如果有NSManagedObject 子类TestEntity,则新语法为

    let entity = TestEntity(context: context)
    entity.testAttribute="test value"
    

    【讨论】:

    • 保存必须被包装到 try-catch 块中。
    • @Mundi 当然可以,但这与问题无关。我删除了该行。
    • 我必须创建 NSEntityDescription 才能使上述代码正常工作。没有它,我得到另一个运行时错误:由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'类'testCoreData.TestEntity'的NSManagedObject必须具有有效的NSEntityDescription。' let entityDes=NSEntityDescription.entity(forEntityName: "TestEntity", in: context) let entity=TestEntity(entity: entityDes!, insertInto: context) entity.testAtt="test attribute" 但后来它奏效了。谢谢。
    • 在 Swift 3 中,Core Data 发生了根本性的变化。例如,有一个新类 NSPersistentContainer 来管理 Core Data 堆栈的创建。创建一个启用 Core Data 的新项目以查看更改。
    【解决方案2】:
    //retrieve the entity
    let entity =  NSEntityDescription.entity(forEntityName: "TestEntity", in: context)
    
    let testEntity = NSManagedObject(entity: entity!, insertInto: context)
    
    //set the entity values
    testEntity.setValue(testAtt1, forKey: "testAtt1")
    testEntity.setValue(testAtt2, forKey: "testAtt2")
    
    //save the object
    do {
        try context.save()
        print("saved!")
    } catch let error as NSError  {
        print("Could not save \(error), \(error.userInfo)")
    } catch {
    
    }
    

    【讨论】:

    • 无法为实体“EntityName”加载名为“ProjectName.EntityName”的类。未找到类,改用默认的 NSManagedObject。
    【解决方案3】:

    工作示例:

    let fr:NSFetchRequest<TestEntity>=TestEntity.fetchRequest()
    do {
        let results=try self.moc!.fetch(fr)
        if results.count==0 {
            print("no resutls. i need to add something")
            let newTestEntity=TestEntity(context: self.moc!)
            newTestEntity.testAtt="testovaci text"
            do {
                try self.moc!.save()
            }catch{
                
            }
        }else{
            print("already some results")
            for result in results {
                print(result.testAtt!)
            }
        }
    }catch {
        print(error)
    }
    

    数据模型检查器TestEntity 类名需要设置为TestEntity。以前的奇怪行为似乎是由于此值为空白引起的。

    【讨论】:

      【解决方案4】:

      我不是 Core Data 专家,但 API 提供了 3 种不同的方法来创建 NSManagedObject 实例。我不知道它们中的任何一个是否比另一个提供任何好处。

      假设您有一个名为 TestEntity 的实体/NSManagedObject 子类,那么以下所有内容都是相同的:


      新方式(无需强制转换)+iOS10:

      let test = TestEntity(context: context)
      test.attribute1 = "a value"
      

      较旧的方式(如果您可以使用setValue,则不需要强制转换。通过强制转换,您可以使用点表示法。+iOS3

      let testEntity =  NSEntityDescription.entity(forEntityName: "TestEntity", in: context)
      
      let test1 = NSManagedObject(entity: testEntity!, insertInto: context)
      test1.setValue("a value", forKey: "attribute1")
      
      let test2 = NSManagedObject(entity: testEntity!, insertInto: context) as! TestEntity
      test2.attribute1 = "a value"
      

      或:

      let test1 = NSEntityDescription.insertNewObject(forEntityName: "TestEntity", into: context)
      test1.setValue("a value", forKey: "attribute1") 
      
      let test2 = NSEntityDescription.insertNewObject(forEntityName: "TestEntity", into: context) as! TestEntity
      test2.attribute1 = "a value"
      

      一旦你创建了 NSManagedObject 实例并分配了它的属性,你就可以将它保存在上下文中。

      do {
          try context.save()
          print("saved!")
      } catch let error as NSError  {
          print("Could not save \(error), \(error.userInfo)")
      } catch {
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多