В настоящее время я обновляю приложение для использования Core Data. Приложение, которое вы могли бы назвать «просмотрщиком базы данных», одновременно может просматривать только одну базу данных. Каждая база данных хранится в отдельной папке. В настоящее время данные загружаются и хранятся в виде набора файлов plist.
В новой версии мне нужно преобразовать эти базы данных plist в хранилища Core Data (по одному хранилищу для каждой базы данных). Я уже настроил методы, создающие отдельные файлы хранилища, и создаю объекты. Проблема в том, что все объекты сохраняются в первую созданную мной базу данных, а не в «текущий» или «последний созданный» файл.
Основной процесс, который я использую:
//For each database {
//Create the sqlite file and set up NSManagedObjectContext
[MagicalRecord setupCoreDataStackWithStoreNamed:
[NSURL fileURLWithPath:
[NSString stringWithFormat:@"%@/%@/%@.sqlite",
dirPath, directory, directory]]];
NSManagedObjectContext *managedObjectContext =
[NSManagedObjectContext MR_contextForCurrentThread];
//Iterate through all the plist files and create the necessary entities.
//Save new entities to file
[managedObjectContext MR_save];
//Clean up all cashes
[MagicalRecord cleanUp];
}
Как правильно переключаться между хранилищами, по сути «сбрасывая» все между каждым переключением. Предпочтительно (если возможно) с использованием магической записи.
РЕДАКТИРОВАТЬ: я обнаружил часть проблемы и удалил большую часть нежелательного поведения. Оказывается, вы не можете надежно вызвать [MagicalRecord cleanUp]
в фоновом потоке. Кроме того, он не делает того, что, по моему мнению, должен (см. ниже). В итоге я перезванивал в основной поток после каждого «сохранения», чтобы сбросить стек Core Data. При этом создается новый контекст для первых трех баз данных. после этого он дублирует контекст из базы данных трехлетней давности. Таким образом, в цикле используются те же три контекста.
Это то, что у меня есть сейчас; Я начинаю процесс с создания фонового потока и запускаю код для создания одной базы данных в фоновом режиме:
backgroundQueue = dispatch_queue_create("com.BrandonMcQuilkin.myQueue", NULL);
dispatch_async(backgroundQueue, ^(void) {
[self createSQLiteDatabase:updateList];
});
Затем создаем стек и базу данных:
- (void)createSQLiteDatabase:(NSArray *)updateList
{
NSString *directory = [updateList objectAtIndex:0];
[MagicalRecord setupCoreDataStackWithStoreNamed:
[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@/%@.sqlite",
dirPath, directory, directory]]];
NSManagedObjectContext *managedObjectContext =
[NSManagedObjectContext MR_contextForCurrentThread];
//Check to see if the stack has reset
NSLog(@"Before:%i", [[Competition MR_findAllInContext:managedObjectContext] count]);
//Create and add entities to context...
//Prepare for next loop
NSLog(@"After:%i", [[Competition MR_findAllInContext:managedObjectContext] count]);
[managedObjectContext MR_saveNestedContexts];
[NSManagedObjectContext MR_resetContextForCurrentThread];
NSMutableArray *temp = [[NSMutableArray alloc] initWithArray:updateList];
[temp removeObjectAtIndex:0];
dispatch_async(dispatch_get_main_queue(), ^(void){
[self shouldContinueUpdating:temp];
});
Затем сбросьте все и повторите для всех баз данных:
- (void)shouldContinueUpdating:(NSArray *)databases
{
//preform cleanup on main thread and release background thread
[MagicalRecord cleanUp];
dispatch_release(backgroundQueue);
if ([databases count] != 0) {
backgroundQueue = dispatch_queue_create("com.BrandonMcQuilkin.myQueue", NULL);
dispatch_async(backgroundQueue, ^(void) {
[self createSQLiteDatabase:databases];
});
}
}
С двумя NSLogs я получаю это в консоли: (используя шесть баз данных, шаблон один и тот же, независимо от того, сколько баз данных я конвертирую).
//First Loop
Before:0
After:308
//Second Loop
Before:0
After:257
//Third Loop
Before:0
After:37
//Fourth Loop
Before:308
After:541
//Fifth Loop
Before:257
After:490
//Sixth Loop
Before:37
After:270
... Keep adding to each of the three contexts.
И [MagicalRecord cleanUp]
не делает того, о чем говорит. Вот что должен делать этот метод.
+ (void) cleanUpStack;
{
[NSManagedObjectContext MR_cleanUp];
[NSManagedObjectModel MR_setDefaultManagedObjectModel:nil];
[NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:nil];
[NSPersistentStore MR_setDefaultPersistentStore:nil];
}
Но получается, что NSStoreCoordinator каждый раз, когда я сохраняю, является одним и тем же координатором, в одной и той же ячейке памяти, и каждый магазин зависает. Что-то работает не так...