CoreData 多个持久存储协调器?

Posted

技术标签:

【中文标题】CoreData 多个持久存储协调器?【英文标题】:CoreData multiple persistent store coordinator? 【发布时间】:2015-11-07 01:53:25 【问题描述】:

我无法完全掌握 CoreData 术语。

我为两个概念上独立的数据集创建了两个 .xcdatamodeld 文件。

一个是关于缓存我从网上下载的静态数据。 一种是关于用户已写但尚未提交到服务器的临时帖子。

这两个数据集根本不需要相互了解。

我想要一个在我尝试更新任何一个时都不会让我头疼的设置。

我需要两个单独的persistent store coordinator 吗?还是两个单独的persistent store?这到底是什么意思?

** 编辑

我猜 Mundi 提出了类似以下的建议。

1 coordinator --- store1 --- model1
      \
       \
         ----- store2 --- model2

如何在代码中实现这一点?

我有以下代码(从教程网站复制),结构或多或少

psc --- model1
  \
   \
     --- store1

而不是

psc --- model1 --- store1

我现有的代码看起来像..

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CachedURLResponse" withExtension:@"momd"];

_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"test.sqlite"];
NSError *error = nil;
[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]

如何在一个协调器中实现模型的单独存储?

我可以为 RDMS 世界中的每个模型使用单独的表。稍后我可以更新表定义,并像我拥有两个独立的数据库一样轻松迁移数据。

我不确定在一个数据库中更新不同的表(模型)是否容易。

【问题讨论】:

【参考方案1】:

与其讨论设置不同商店协调器和上下文的架构复杂性,我会简单地创建两个不同的商店和不同的实体,以确保两个数据集不会相互干扰。

这将满足您“最少头痛”的要求,同时让您使用普通的香草代码。

多店多款基本流程如下:

在模型中,将您的实体包含在“配置”中,为两个商店使用不同的名称。 在设置 Core Data 堆栈时,合并模型 与其仅向协调器添加一个配置为nil 的持久存储,不如添加两个具有各自配置名称的存储。

【讨论】:

感谢您的建议。虽然我无法将您的想法转化为代码。我已经编辑了问题,请看一下。【参考方案2】:

从概念上讲,持久存储类似于数据库;它是存储符合某种模式的数据的地方。持久存储协调器管理对一个或多个持久存储的读取和写入。

您希望如何构建 CoreData 堆栈可能取决于您希望如何查询数据。

如果这两个数据集完全不同,您可以为每个数据集提供自己的存储和协调器以及托管对象上下文。但是,在这种情况下,您将无法为“所有已保存或未保存的帖子”构建查询(通过NSFetchRequest),您可能需要做一些额外的工作来跟踪帖子何时从一个状态移动以确保您不会在两个商店中存储同一帖子的版本。

如果您确实需要查询两组数据,那么您需要一个协调器来管理每个商店中保存的实体。这需要您在协调器中做一些工作,但可能会让应用程序的其余部分不了解这些持久存储的机制。

您需要决定哪条路径更容易使用和维护。

【讨论】:

【参考方案3】:

如果您想拥有一个合并模型,您可以在代码中完成,而无需更改您的模型文件。

假设有两个模型,“CachedURLResponse”和“TemporaryPosts”,您想要一个包含每个模型中所有实体的单独存储,您可以这样做。

- (NSString*)configurationForModelNamed:(NSString*)modelName 
    return [modelName stringByAppendingString:@".config"];


- (NSURL*)URLForModelNamed:(NSString*)modelName 
    NSString *name = [modelName stringByAppendingString:@".sqlite"];
    return [[self applicationDocumentsDirectory] URLByAppendingPathComponent:name];


- (NSManagedObjectModel*)mergedModelForModelNames:(NSArray*)modelNames 
    NSMutableArray *models = [[NSMutableArray alloc] init];
    for (NSString * name in modelNames) 
        NSURL *modelURL = [[NSBundle mainBundle] URLForResource:name withExtension:@"momd"];
        NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
        [model setEntities:model.entities forConfiguration:[self configurationForModelNamed:name]];
        [models addObject:model];
    
    return [NSManagedObjectModel modelByMergingModels:models];


- (NSPersistentStoreCoordinator*)pscForModelNames:(NSArray*)modelNames 
    NSManagedObjectModel *model = [self mergedModelForModelNames:modelNames];
    NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
    for (NSString *name in modelNames) 
        NSError *error = nil;
        if (![psc addPersistentStoreWithType:NSSQLiteStoreType
                               configuration:[self configurationForModelNamed:name]
                                         URL:[self URLForModelNamed:name]
                                     options:nil
                                       error:&error]) 
            // Handle error...
        
    

然后,您可以使用任何您想要的 momd 模型创建 PSC...

NSPersistentStoreCoordinator *psc = [self pscForModelNames:@[@"CachedURLResponse", @"TemporaryPosts"]];

【讨论】:

以上是关于CoreData 多个持久存储协调器?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以创建自定义核心数据持久存储协调器?

核心数据:无法将持久存储添加到协调器

iOS 7 中的 CoreData 迁移

无需迁移即可替换核心数据模型

两个托管对象上下文可以共享一个持久存储协调器吗?

核心数据持久存储协调器不存在