我想将一个sqlite文件(使用带有模型A的Core Data创建的)的内容追加到我的应用程序使用的另一个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];
答案 0 :(得分:1)
我立即在代码中看到一个错误,这与该方法调用的错误参数有关。 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
}
答案 1 :(得分:0)
感谢Brian指出这一点。
我最后只是将附加的sqlite文件添加到堆栈的持久存储中,效果非常好,并允许我们稍后将fetchRequest限制为单个存储:
NSError *error = nil;
NSURL *url = SOME_FILEPATH_URL;
NSPersistentStore *newStore = [persistentStoreCoordinator
addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:url
options:opt
error:&error];
我们保留所有persistentStore的字典供以后参考。