【问题标题】:Core Data creating extra, empty store when updating app更新应用程序时核心数据创建额外的空存储
【发布时间】:2017-08-04 17:53:11
【问题描述】:

我正在对一个使用了几年并使用 Core Data 的应用进行更新。以前的版本将其数据存储在 Documents/app-name.sqlite 中。我没有在更新中更改任何与数据相关的代码,但是当我第一次启动新版本时,它在 Library/Application Support/app-name.sqlite 创建了一个新的空数据存储。 我不知道如何解决这个问题。

Core Data 的初始设置如下所示:

    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:SKCoreDataModelName withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];


    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:[SKCoreDataModelName stringByAppendingString:@".sqlite"]];
    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    NSDictionary *opts = [NSDictionary dictionaryWithObjectsAndKeys:
                          [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                          [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                          nil];
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:opts error:&error]) {
        SKLogError(@"Unresolved error when creating persistent store coordinator %@, %@", error, [error userInfo]);
    }

这似乎在新版本中正常工作:没有触发错误,没有创建新数据库。当我实例化持久化容器时出现问题:

        _persistentContainer = [[NSPersistentContainer alloc] initWithName:SKCoreDataModelName];
        [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) { ... }];

通过这个可以看到,当我初始化NSPersistentContainer时,模拟器数据中出现了Library/Application Support文件夹;当我调用loadPersistentStoresWithCompletionHandler 时,新的sqlite 文件就会出现。

这里发生了什么,更重要的是,我该如何解决?谢谢。

【问题讨论】:

    标签: ios core-data


    【解决方案1】:

    新的 NSPersistentContainer 类对它在何处/如何创建事物有一些约定。默认情况下,当你传入 {name} 时,它会查找名为“{name}.momd”的模型文件,并会在“Application Support”中创建一个名为“{name}.sqlite”的 sqlite 文件。这些默认值可以被覆盖。

    在创建容器之后,调用 load 之前,你应该这样做:

    斯威夫特:

    let description = NSPersistentStoreDescription(url: storeURL );
    _persistentContainer.persistentStoreDescriptions = [description];
    

    对象-C:

    NSPersistentStoreDescription *_description = [NSPersistentStoreDescription persistentStoreDescriptionWithURL:storeUrl: storeUrl];
     _persistentContainer.persistentStoreDescriptions = @[description]; 
    

    这将重置用于商店的默认网址。

    【讨论】:

    • 就是这样!非常感谢! (请注意,实例化商店描述的调用实际上是 [NSPersistentStoreDescription persistentStoreDescriptionWithURL:storeUrl]。)不过,老实说,我宁愿将事情转移到默认值......将现有商店迁移到应用程序支持中的标准位置?
    • 我不知道是否有办法自动完成,我可能只是使用 NSFileManager 手动移动它。
    猜你喜欢
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 2012-01-31
    • 1970-01-01
    相关资源
    最近更新 更多