CoreData 严重应用程序错误:实体不符合键值编码

Posted

技术标签:

【中文标题】CoreData 严重应用程序错误:实体不符合键值编码【英文标题】:CoreData Serious Application Error: Entity is not key value coding-compliant 【发布时间】:2013-07-12 12:22:39 【问题描述】:

我是 CoreData 和 Restkit 的新手,遇到以下错误时遇到了很多麻烦。

我正在使用 restkit 来解析从 Foursquare 返回的一些场所。不幸的是,我不断收到此错误:

2013-07-12 16:12:46.369 FlokMobile[5903:c07] CoreData: error: Serious application error.  Exception was caught during Core Data change processing.  This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.  [<FoursquareVenue 0x1ec5fb00> valueForUndefinedKey:]: the entity Venue is not key value coding-compliant for the key "distance". with userInfo 
    NSTargetObjectUserInfoKey = "<FoursquareVenue: 0x1ec5fb00> (entity: Venue; id: 0xb472c10 <x-coredata://EAB387D9-C6CB-4873-84C5-1C32E137FFE9/Venue/p49> ; data: \n    canonicalUrl = \"https://foursquare.com/v/sams-cable-car-lounge/5171ef7b498e4035a7f7a371\";\n    location = \"0xb477860 <x-coredata://EAB387D9-C6CB-4873-84C5-1C32E137FFE9/Location/p30>\";\n    name = \"Sam's Cable Car Lounge\";\n    venueID = 5171ef7b498e4035a7f7a371;\n)";
    NSUnknownUserInfoKey = distance;

2013-07-12 16:12:46.370 FlokMobile[5903:c07] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<FoursquareVenue 0x1ec5fb00> valueForUndefinedKey:]: the entity Venue is not key value coding-compliant for the key "distance".'
*** First throw call stack:
(0x1e42012 0x1c67e7e 0x1ecafb1 0x24d1d4 0x168000b 0x1e8fc4 0x169e247 0x1738c62 0x2af8a5 0x2aa735 0x2ad011 0x17284f9 0x1e9c0c5 0x1df6efa 0x165cbb2 0x1bf163 0x258d2f 0x1ba596 0x1b9869 0x1e6558 0x25b025 0x1e0cc1 0x2697731 0x26a6014 0x26967d5 0x1de8af5 0x1de7f44 0x1de7e1b 0x28dd7e3 0x28dd668 0xbabffc 0x2e7d 0x2da5)
libc++abi.dylib: terminate called throwing an exception

这是我用来设置键映射的代码:

// Setup Restkit for Foursquare

//Setup mapping for response
NSError *error = nil;
NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"FoursquareModel" ofType:@"momd"]];
//mutableCopy might not be necessary
NSManagedObjectModel *managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];

//Initialize Core Data stack
[managedObjectStore createPersistentStoreCoordinator];

NSPersistentStore __unused *persistentStore = [managedObjectStore addInMemoryPersistentStore:&error];
NSAssert(persistentStore, @"Failed to add persistent store: %@", error);

[managedObjectStore createManagedObjectContexts];

//Set default store shared instance
[RKManagedObjectStore setDefaultStore:managedObjectStore];

//Configure Object Manager
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"https://api.foursquare.com/v2/"]];
objectManager.managedObjectStore = managedObjectStore;

[RKObjectManager setSharedManager:objectManager];

RKEntityMapping *venueMapping = [RKEntityMapping mappingForEntityForName:@"Venue" inManagedObjectStore:managedObjectStore];
RKEntityMapping *locationMapping = [RKEntityMapping mappingForEntityForName:@"Location" inManagedObjectStore:managedObjectStore];

[venueMapping addAttributeMappingsFromDictionary:@
 @"name":         @"name",
 @"id":           @"venueID",
 @"canonicalUrl": @"canonicalUrl"];
venueMapping.identificationAttributes = @[@"venueID"];

[locationMapping addAttributeMappingsFromArray:@[ @"address",@"cc",@"city",@"country",@"crossStreet",@"distance",@"lat",@"lng",
                                     @"postalCode",@"state"]];

//[venueMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"location" toKeyPath:@"location" withMapping:locationMapping]];
[venueMapping addRelationshipMappingWithSourceKeyPath:@"response.venues.location" mapping:locationMapping];


RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor
                                            responseDescriptorWithMapping:venueMapping
                                            pathPattern:nil
                                            keyPath:@"response.venues"
                                            statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

[objectManager addResponseDescriptor:responseDescriptor];

还有我的 CoreData 模型:

每次我运行应用程序时,它总是无法对相同的密钥进行编码。它能够加载场地并将密钥映射到场地实体。我认为我处理 Venue 和 Location 实体之间关系的方式可能存在问题。

这是我得到的 JSON 的样子:


  "meta" : 
    "code" : 200
  ,
  "response" : 
    "venues" : [
      
        "id" : "40bbc700f964a520b1001fe3",
        "categories" : [
          
            "pluralName" : "Plazas",
            "primary" : true,
            "shortName" : "Plaza",
            "id" : "4bf58dd8d48988d164941735",
            "name" : "Plaza",
            "icon" : 
              "prefix" : "https://foursquare.com/img/categories_v2/parks_outdoors/plaza_",
              "suffix" : ".png"
            
          
        ],
        "stats" : 
          "checkinsCount" : 75856,
          "usersCount" : 40342,
          "tipCount" : 176
        ,
        "venuePage" : 
          "id" : "34303229"
        ,
        "storeId" : "",
        "contact" : 
          "phone" : "4157817880",
          "formattedPhone" : "(415) 781-7880",
          "twitter" : "unionsquaresf"
        ,
        "hereNow" : 
          "groups" : [],
          "count" : 0
        ,
        "verified" : true,
        "url" : "http://visitunionsquaresf.com",
        "referralId" : "v-1373553758",
        "restricted" : true,
        "location" : 
          "address" : "Union Square Park",
          "city" : "San Francisco",
          "distance" : 68,
          "postalCode" : "94108",
          "crossStreet" : "btwn Post, Stockton, Geary & Powell St.",
          "country" : "United States",
          "lat" : 37.787750172585,
          "lng" : -122.40762822536455,
          "state" : "CA",
          "cc" : "US"
        ,
        "canonicalUrl" : "https://foursquare.com/v/union-square/40bbc700f964a520b1001fe3",
        "specials" : 
          "count" : 0,
          "items" : []
        ,

【问题讨论】:

您是单独做项目还是使用 SCM?在第二种情况下,清理构建非常有用。 这是您的整个映射代码吗?它看起来正确,但错误消息看起来与代码所说的不匹配...... 我一个人工作。我已经清理了构建和目录。我应该发布更多上下文吗?我不想放太多不相关的代码。 一切似乎都已正确连接。一个疯狂的预感:你有模型版本吗?会不会是当前模型版本设置为没有距离键的旧版本? 我该如何检查呢?我是 CoreData 的新手! 【参考方案1】:

所以这就是我的想法:Restkit,出于某种奇怪的原因正在实体“地点”中寻找关键的“距离”

“距离”不是从 Foursquare 接收到的 JSON 中的属性,也不是通过代码显式映射到任何地方。

我通过将“距离”键添加到“地点”实体来暂时解决了当前问题。我不知道它为什么会起作用,以后可能会产生一些奇怪的影响。

如果有人能更深入地了解这个问题,我将不胜感激。 希望我在我的代码中做错了什么,我只是没有看到它!

编辑:即使有 Blake 的建议,我也遇到了同样的错误。

【讨论】:

您的代码在哪里调用 nsmanagedobject 的 init。错误的键可能来自调用不完整的 initWithEntity:inManagedObjectContext: 或 managedobjectcontext 无效。 有时模型会损坏并且无法保存,从而丢失了一个新属性【参考方案2】:

我认为您的响应描述符和关系映射关键路径都被扭曲了。您在描述符中双重指定 response.venues 键路径,然后在自引用关系映射中再次指定。试试这个:

RKEntityMapping *venueMapping = [RKEntityMapping mappingForEntityForName:@"Venue" inManagedObjectStore:managedObjectStore];
RKEntityMapping *locationMapping = [RKEntityMapping mappingForEntityForName:@"Location" inManagedObjectStore:managedObjectStore];

[venueMapping addAttributeMappingsFromDictionary:@
 @"name":         @"name",
 @"id":           @"venueID",
 @"canonicalUrl": @"canonicalUrl"];
venueMapping.identificationAttributes = @[@"venueID"];

[locationMapping addAttributeMappingsFromArray:@[ @"address",@"cc",@"city",@"country",@"crossStreet",@"distance",@"lat",@"lng",
                                     @"postalCode",@"state"]];
[venueMapping addRelationshipMappingWithSourceKeyPath:@"location" mapping:locationMapping];


RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor
                                            responseDescriptorWithMapping:venueMapping
                                            pathPattern:nil
                                            keyPath:@"response.venues"
                                            statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

[objectManager addResponseDescriptor:responseDescriptor];

使用日志记录或单元测试可以更轻松地调试映射。

【讨论】:

感谢您的帮助!不幸的是,即使进行了更改,我仍然遇到同样的错误。

以上是关于CoreData 严重应用程序错误:实体不符合键值编码的主要内容,如果未能解决你的问题,请参考以下文章

Core Data 此类不符合键名的键值编码

实体 xxx 不符合键“(null)”的键值编码

Restkit - 实体(空)不符合键“行”的键值编码

绑定和核心数据:实体 xxx 不符合键“(null)”的键值编码

iOS中的键值类型强制

即使在重新启动我的开发 Mac 之后,实体仍然不符合键的键值编码