Restkit + Core Data:每次应用启动时在 UITableView 中插入重复值

Posted

技术标签:

【中文标题】Restkit + Core Data:每次应用启动时在 UITableView 中插入重复值【英文标题】:Restkit + Core Data: Inserts duplicate values in a UITableView on every app launch 【发布时间】:2013-07-11 06:54:52 【问题描述】:

在AlexEdge Tutorial 之后,我遇到了以下行为。我可以按要求提供代码,因为有很多行,我不确定在哪里看。基本上,它在数据被正确加载到 UITableView 的意义上“工作”,但是在停止并启动模拟器后,它会在每个部分中插入新的重复行。

我认为这与缓存有关,但我非常密切地遵循上述教程,并且我设置了 identificationAttributes 来识别唯一记录(例如,添加所有属性不会有效地消除这种可能性我没有指定一个足够唯一的密钥,只是为了调试目的?)。我尝试更改缓存名称,将其设置为零,但它不断插入重复项。每隔一段时间,我都会重置模拟器以重新开始。

如果重要,我会按照教程在viewDidLoad 中调用getObjectsAtPath。我对 RestKit 工作原理的理解是,这样做是可以的,因为它足够聪明,可以推断出不需要更新,因为记录都是一样的。

编辑

我已将identificationAttributes 设置为一个由两个整数属性组成的数组,它们确实确定了一条唯一记录。

我还有一个managedObjectCache

// Seal the deal

[managedStore createPersistentStoreCoordinator];

NSString *storePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"CCTDB.sqlite"];

NSError *error;

NSPersistentStore *persistentStore =
[managedStore
 addSQLitePersistentStoreAtPath:storePath
 fromSeedDatabaseAtPath:nil
 withConfiguration:nil
 options:@
    NSMigratePersistentStoresAutomaticallyOption:@YES,
    NSInferMappingModelAutomaticallyOption:@YES
 
 error:&error];

NSAssert(persistentStore, @"Failed to add persistent store with error: %@", error);

[managedStore createManagedObjectContexts];

managedStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedStore.persistentStoreManagedObjectContext];

编辑 1

这是第二次的日志输出

(2013-07-11 03:18:29.961 cocoaclinical[18773:3d07] D restkit.object_mapping:RKPropertyInspector.m:130 Cached property inspection for Class 'EMDisease': 
    diseaseId =     
        isPrimitive = 0;
        keyValueCodingClass = NSNumber;
        name = diseaseId;
    ;
    diseaseIdValue =     
        isPrimitive = 1;
        keyValueCodingClass = NSNumber;
        name = diseaseIdValue;
    ;
    name =     
        isPrimitive = 0;
        keyValueCodingClass = NSString;
        name = name;
    ;
    subDiseaseId =     
        isPrimitive = 0;
        keyValueCodingClass = NSNumber;
        name = subDiseaseId;
    ;
    subDiseaseIdValue =     
        isPrimitive = 1;
        keyValueCodingClass = NSNumber;
        name = subDiseaseIdValue;
    ;

2013-07-11 03:18:29.975 cocoaclinical[18773:3f03] I restkit.core_data:RKInMemoryManagedObjectCache.m:94 Caching instances of Entity 'EMDisease' by attributes 'diseaseId, subDiseaseId'
2013-07-11 03:18:29.983 cocoaclinical[18773:3f03] T restkit.core_data:RKInMemoryManagedObjectCache.m:127 Cached 31 objects
2013-07-11 03:18:29.984 cocoaclinical[18773:3f03] D restkit.object_mapping:RKMapperOperation.m:231 Asked to map source object 
    DiseaseSystemIdMember = 161;
    DisplayNameMember = "Acute Lymphocytic Leukemia";
    SubDiseaseSystemIdMember = 1886;
 with mapping <RKEntityMapping:0x96c2850 objectClass=EMDisease propertyMappings=(
    "<RKAttributeMapping: 0x96ba060 SubDiseaseSystemIdMember => subDiseaseId>",
    "<RKAttributeMapping: 0xb58df40 DisplayNameMember => name>",
    "<RKAttributeMapping: 0xb58df70 DiseaseSystemIdMember => diseaseId>"
)>
2013-07-11 03:18:29.984 cocoaclinical[18773:3f03] D restkit.object_mapping:RKMappingOperation.m:952 Starting mapping operation...
2013-07-11 03:18:29.985 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:953 Performing mapping operation: <RKMappingOperation 0xb5b7820> for 'EMDisease' object. Mapping values from object 
    DiseaseSystemIdMember = 161;
    DisplayNameMember = "Acute Lymphocytic Leukemia";
    SubDiseaseSystemIdMember = 1886;
 to object <EMDisease: 0xb5b7ee0> (entity: EMDisease; id: 0xb5b7f80 <x-coredata:///EMDisease/t8DD8EE18-C798-468F-9E03-C6A3C724AA772> ; data: 
    diseaseId = 161;
    name = nil;
    subDiseaseId = 1886;
) with object mapping (null)
2013-07-11 03:18:30.027 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:550 Mapping attribute value keyPath 'SubDiseaseSystemIdMember' to 'subDiseaseId'
2013-07-11 03:18:30.028 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:583 Skipped mapping of attribute value from keyPath 'SubDiseaseSystemIdMember to keyPath 'subDiseaseId' -- value is unchanged (1886)
2013-07-11 03:18:30.029 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:550 Mapping attribute value keyPath 'DisplayNameMember' to 'name'
2013-07-11 03:18:30.029 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:572 Mapped attribute value from keyPath 'DisplayNameMember' to 'name'. Value: Acute Lymphocytic Leukemia
2013-07-11 03:18:30.030 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:550 Mapping attribute value keyPath 'DiseaseSystemIdMember' to 'diseaseId'
2013-07-11 03:18:30.030 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:583 Skipped mapping of attribute value from keyPath 'DiseaseSystemIdMember to keyPath 'diseaseId' -- value is unchanged (161)
2013-07-11 03:18:30.031 cocoaclinical[18773:3f03] D restkit.object_mapping:RKMappingOperation.m:1021 Finished mapping operation successfully...

【问题讨论】:

【参考方案1】:

你确实需要设置identificationAttributes,不过一般只有一两个属性,不是全部。您的实体应该有一些唯一标识符。

您还想将managedObjectCache 添加到您的托管对象存储中。这是允许 RestKit 使用您的 identificationAttributes 匹配对象并更新现有项目而不是创建新项目的部分。

【讨论】:

感谢您的建议,请参阅我的编辑 - 我认为我已经完成了您的建议... 获取结果控制器中的部分名称键路径(如果有的话)如何影响这一点? FRC 用于显示,与映射过程中的任何重复无关。 此日志消息是否有任何相关性? Detected observation of ancestor context by child: enabling child context save detection 我想我想知道的是什么会提示我,明智地记录,就像“好的,这还没有在缓存中,所以我应该添加这个”跨度>

以上是关于Restkit + Core Data:每次应用启动时在 UITableView 中插入重复值的主要内容,如果未能解决你的问题,请参考以下文章

RESTkit,Core Data:在将对象传输到 Core Data 之前对其进行处理

Core Data 和 Restkit 简单轻量级迁移错误

Core Data + RestKit 映射多对多关系?

Restkit, Swift, Core data 一对多

与 Core Data 和 RestKit 无关的关系

RestKit / Core Data / Offline - 我需要 UUID 还是 RestKit 足够聪明?