Restkit + Core Data: вставляет повторяющиеся значения в UITableView при каждом запуске приложения.

Следуя руководству AlexEdge, я столкнулся с следующее поведение. Я могу предоставить код по запросу, так как строк много, и я не совсем уверен, где искать. По сути, он «работает» в том смысле, что данные правильно загружаются в UITableView, но после остановки и запуска симулятора он вставляет в каждую секцию новые повторяющиеся строки.

Я полагал, что это как-то связано с кэшированием, но я очень внимательно следую приведенному выше руководству и установил identificationAttributes для идентификации уникальных записей (например, добавление ВСЕХ атрибутов не устранит возможность того, что я не указал достаточно уникальный ключ, только для целей отладки?). Я попытался изменить имя кеша, установив его на ноль, но он продолжает вставлять дубликаты. Время от времени я перезагружаю симулятор, чтобы начать с чистого листа.

Если это имеет значение, я звоню getObjectsAtPath в viewDidLoad в соответствии с учебным пособием. Мое понимание того, как работает 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...

person tacos_tacos_tacos    schedule 11.07.2013    source источник


Ответы (1)


Вам нужно установить identificationAttributes, хотя обычно только один или два атрибута, а не все. Ваши объекты должны иметь какой-то уникальный идентификатор.

Вы также хотите добавить managedObjectCache в хранилище управляемых объектов. Это та часть, которая позволяет RestKit сопоставлять объекты с помощью вашего identificationAttributes и обновлять существующие элементы вместо создания новых.

person Wain    schedule 11.07.2013
comment
Спасибо за предложения, посмотрите мое редактирование - я думаю, что сделал то, что вы предложили... - person tacos_tacos_tacos; 11.07.2013
comment
Как влияет на это путь ключа имени раздела (если вообще) в извлеченном контроллере результатов? - person tacos_tacos_tacos; 11.07.2013
comment
FRC предназначен для отображения и не связан с каким-либо дублированием во время сопоставления. - person Wain; 11.07.2013
comment
Может ли это сообщение журнала иметь какое-либо значение? Detected observation of ancestor context by child: enabling child context save detection - person tacos_tacos_tacos; 11.07.2013
comment
Я предполагаю, что мне интересно, что могло бы подсказать мне, с точки зрения ведения журнала, где это похоже на Хорошо, это еще НЕ в кеше, поэтому я действительно должен добавить это - person tacos_tacos_tacos; 11.07.2013
comment
Итак, в сопоставлении был мошенник IdentifiationPredicate, который, по-видимому, вызывал проблему. Удаление предиката решило проблему, но почему это вызвало проблему? - person tacos_tacos_tacos; 11.07.2013