为什么我收到“实体 X 不符合键值编码”?

kon*_*v12 8 core-data ios swift

当我运行以下代码时:

    let saveAction = UIAlertAction(title: "Save",
                                   style: .default) {
    [unowned self] action in
    guard let textField = alert.textFields?.first,
    let mapName = textField.text else {
    return
    }
    var newCoordinate = NSEntityDescription.insertNewObject(forEntityName: "Coordinates", into: managedObjectContext)

    var newMap = NSEntityDescription.insertNewObject(forEntityName: "MapNames", into: managedObjectContext)

    newCoordinate.setValue(23, forKey: "latitude")
    newCoordinate.setValue(21, forKey: "longitude")
    newMap.setValue(mapName, forKey: "mapname")

    do
    {
    try self.appDelegate.saveContext()
    print("SAVED")
    }
    catch
    {
    }

    var request = NSFetchRequest<NSFetchRequestResult>(entityName: "Coordinates")
    request.returnsObjectsAsFaults = false

    do
    {
    var results = try managedObjectContext.fetch(request)

        if results.count > 0 {
        for result in results as! [NSManagedObject]
        {
            if let latitude = result.value(forKey: "latitude") as? Double
            {
            print(latitude)
            }
            if let longitude = result.value(forKey: "longitude") as? Double{
            print(longitude)}
            if let map = result.value(forKey: "mapname") as? String {
            print(map)}

        }
    }
    }
    catch
    {
    }
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“[ valueForUndefinedKey:]:实体坐标与键“mapname”的键值编码不兼容。”

这很奇怪,因为我确实有一个名为 mapname 的属性,尽管它位于 MapNames 实体中。错误显示坐标,这是为什么?

这是因为在同一范围内不可能有 2 个对 ManagedObjectContext 的引用吗?那么我怎样才能将值插入到不同的实体中呢?

Sul*_*han 5

你的插入代码没有问题。但是,让我们看看您的获取代码:

var request = NSFetchRequest<NSFetchRequestResult>(entityName: "Coordinates")
Run Code Online (Sandbox Code Playgroud)

您将在此处创建一个获取坐标的请求。

根据该请求的结果(即 a Coordinates),您正在调用:

if let map = result.value(forKey: "mapname") as? String {
   print(map)
}
Run Code Online (Sandbox Code Playgroud)

这显然是不正确的。

理想情况下,您应该使用 的Coordinates子类NSManagedObject并直接使用以下属性,而不是使用危险的 KVC:

var request = NSFetchRequest<Coordinates>(entityName: "Coordinates")

... 

for result in results as! [Coordinates] {
   print(result.latitude)
   print(result.longitude)
}
Run Code Online (Sandbox Code Playgroud)


RBr*_*ink 5

升级到 Swift 4 后我遇到了同样的错误。

我必须将@objcMembers添加到我的实体类(或将@objc添加到该类的每个属性)。