Cocoa 使用NSMigrationManager将数据附加到核心数据持久存储

Cocoa 使用NSMigrationManager将数据附加到核心数据持久存储,cocoa,sqlite,core-data,migration,Cocoa,Sqlite,Core Data,Migration,我想将一个sqlite文件(使用模型a的核心数据创建)中的内容附加到我的应用程序使用的另一个sqlite存储(使用相同的模型a)。其想法是快速导入大量数据 我面临的问题是,下面的代码只工作一次。当我尝试两次运行同一代码时,应用程序将在我用注释标记的行中崩溃。任何帮助都将不胜感激 NSError **err; NSURL *importURL = [NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppend

我想将一个sqlite文件(使用模型a的核心数据创建)中的内容附加到我的应用程序使用的另一个sqlite存储(使用相同的模型a)。其想法是快速导入大量数据

我面临的问题是,下面的代码只工作一次。当我尝试两次运行同一代码时,应用程序将在我用注释标记的行中崩溃。任何帮助都将不胜感激

NSError **err;
NSURL *importURL = [NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath]  stringByAppendingPathComponent: @"import.sqlite"]];
NSURL *storeURL = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"applicationdata.sqlite"]];
NSMigrationManager *migrator = [[NSMigrationManager alloc] initWithSourceModel:[self managedObjectModel] destinationModel:[self managedObjectModel]];
NSMappingModel *mappingModel = [NSMappingModel inferredMappingModelForSourceModel:[self managedObjectModel] destinationModel:[self managedObjectModel] error:err];
NSError **err2;

// the following line crashes when the whole block is ran twice
[migrator migrateStoreFromURL:importURL 
                         type:NSSQLiteStoreType 
                      options:nil 
             withMappingModel:mappingModel 
             toDestinationURL:storeURL 
              destinationType:NSSQLiteStoreType 
           destinationOptions:nil 
                        error:err2];

NSLog(@"import finished");
[migrator release];

我马上在代码中看到了一个错误,这与方法调用的error参数有关。
NSError**
表示您希望为方法提供一个
NSError*
的地址,它将使用该地址写出对错误对象的引用(如果发生错误)。现在,您只需要传入一个未初始化的指针,它可以指向有效的内容,也可以指向总垃圾量,具体取决于当时堆栈上发生了什么。迁移器的方法将写到这一点,有时没有明显的不良影响,但有时会导致崩溃,如您所见。其代码如下所示:

NSError *err2 = nil; //you want to initialize to nil, in case method doesn't modify your pointer at all (i.e. no error occurs)

//the method also returns a BOOL indicating success/failure
if (![migrator migrateStoreFromURL:importURL 
                     type:NSSQLiteStoreType 
                  options:nil 
         withMappingModel:mappingModel 
         toDestinationURL:storeURL 
          destinationType:NSSQLiteStoreType 
       destinationOptions:nil 
                    error:&err2])
{
    //handle the error
}

谢谢布莱恩指出这一点

最后,我简单地将额外的sqlite文件添加到堆栈的持久存储中,效果非常好,并允许我们稍后将fetchRequest限制到单个存储:

NSError *error = nil;
NSURL *url = SOME_FILEPATH_URL;
NSPersistentStore *newStore = [persistentStoreCoordinator 
                                    addPersistentStoreWithType:NSSQLiteStoreType
                                                 configuration:nil
                                                           URL:url 
                                                       options:opt
                                                         error:&error];
我们还保留了一个所有persistentStores的字典,以供以后参考