【问题标题】:Using NSMigrationManager to append data to Core Data Persistent Store使用 NSMigrationManager 将数据附加到 Core Data Persistent Store
【发布时间】:2010-12-10 10:41:49
【问题描述】:

我想将一个 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];

【问题讨论】:

    标签: cocoa sqlite core-data migration


    【解决方案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
    }
    

    【讨论】:

      【解决方案2】:

      感谢布赖恩指出这一点。

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

      NSError *error = nil;
      NSURL *url = SOME_FILEPATH_URL;
      NSPersistentStore *newStore = [persistentStoreCoordinator 
                                          addPersistentStoreWithType:NSSQLiteStoreType
                                                       configuration:nil
                                                                 URL:url 
                                                             options:opt
                                                               error:&error];
      

      我们保留所有持久存储的字典以供以后参考。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-22
        • 1970-01-01
        • 2015-08-21
        • 1970-01-01
        • 2013-10-08
        相关资源
        最近更新 更多