我目前正在更新一个应用程序以使用 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]
后台线程。此外,它没有做我认为应该做的事情(见下文)。我最终在每次“保存”后回调主线程以重置核心数据堆栈。这样做会为前三个数据库创建一个新的上下文。之后,它从三个数据库前的数据库中复制上下文。因此,在循环中使用了相同的三个上下文。
这是我目前拥有的;我通过创建一个后台线程来启动该过程并运行代码以在后台创建单个数据库:
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];
});
}
}
使用两个 NSLog,我在控制台中得到了这个:(使用六个数据库,无论我转换多少个数据库,模式都是相同的。)
//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 都是同一个协调器,在同一个内存位置,每个商店都在闲逛。有些东西不正常...