gpt4 book ai didi

sqlite - 将一个 ManagedObjectContext 和 PersistentStoreCoordinator 与两个存储一起使用时如何保存数据

转载 作者:行者123 更新时间:2023-12-03 17:08:43 25 4
gpt4 key购买 nike

问题说明

当尝试将记录保存到分配给同一个 PersistentStoreCoordinator 的两个 SQLite 存储之一的读/写存储时,我的 iPhone 应用程序崩溃。保存记录时一个明显的问题是 PersistentStoreCoordinator 不知道在哪个 Store 中保存数据(只是因为我不知道如何做到这一点)。

首先,我将提供大局以确保我的方法是合理的。然后我将提供实现细节。

背景

这是一个简化的示例,代表了我正在开发的实际应用程序的关键方面。

Managed Object Model

种子数据

Seed Data

用户输入场景

User Input Scenario

当前实现

核心数据实现

Core Data Implementation

数据存储和检索

Data Storage and Retrieval

当然,在查看选择列表以对属性进行选择时,不应该向用户证明这些选择来自两个不同的 Store。

持久存储协调器设置

- (NSPersistentStoreCoordinator*)persistentStoreCoordinator {
if (_persistentStoreCoordinator == nil) {
NSArray *bundles = @[[NSBundle bundleForClass:[self class]]];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:bundles]];

NSError *error;
//--------------------------------------------------
// Set options for the USER DATA Persistent Store.
NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES};
//--------------------------------------------------
// Add the USER DATA Store to the Persistent Store Coordinator.
NSPersistentStore *persistentStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.persistentStorePathForUserData
options:options
error:&error];
//--------------------------------------------------
// Set options for the SEED DATA Persistent Store.
options = @{NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES,
NSReadOnlyPersistentStoreOption : @YES};
//--------------------------------------------------
// Add the SEED DATA Store to the Persistent Store Coordinator.
persistentStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.persistentStorePathForSeedData
options:options
error:&error];
}
return _persistentStoreCoordinator;
}

重要目标

请记住以下几点:
  • 如果可能的话,我更愿意在无需管理幕后数据版本的情况下进行种子数据更新(即仅提供应用程序更新的种子数据记录是新的或已更改并以某种方式处理删除)或在中实现版本检查功能处理用户从版本 n 升级到 n+5 的情况的代码。
  • 用户数据和种子数据不应包含两者之间的任何重复记录并使用相同的 ManagedObjectModel。因此,从数据和模型的角度来看,应该不需要合并两个商店或将一个商店迁移到另一个商店。

  • 科研

    在这种情况下,
    Save objects from multiple stores to single persistent store ,
    合并两个 Store,然后获取所有记录,剔除重复项并保存上下文。我希望不必合并然后检查数千条记录是否有重复项。 (请参阅上面的重要目标 #2。)

    在这种情况下,
    What is an efficient way to Merge two iOS Core Data Persistent Stores? ,
    某些实体是只读的,而其他实体是读/写的。在我的应用程序中,种子数据存储中的所有实体都是只读的,而用户数据存储中的相同实体都是读/写的。所以我不认为迁移是适用的。 (请参阅上面的重要目标 #2。)

    在苹果公司, Core Data Programming Guide在“Persistent Store Coordinator”下,图 4“Advanced persistence stack”显示了使用两个 Store 的 Core Data 实现,但同样,每个 Store 都配置有单独且不同的对象。在我的应用程序中,每个对象都出现在每个 Store 中。

    这里提出的解决方案,
    Combining Two SQLite Stores Into One ,
    相对于在不同商店中的对象之间没有关系的两个商店似乎相关,但没有提供与我实现的内容进行比较的详细信息。

    我已经看完了, Core Data (2nd Edition), by Marcus Zarra的前三章,但他不会使用两个不需要迁移的商店。然而,第 3 章确实提供了一个非常清晰的版本控制示例。 (它的复杂性使我达到了上面的重要目标#1。)

    这个解决方案, Which persistent store is used by default in core data in iPhone ,建议使用 ManagedObjectModel 的多个配置,但每个实体都分配给一个且仅一个配置。我不确定这个解决方案如何或是否可以推断到我的情况。

    也许这里提出的解决方案, NSPersistentStoreCoordinator with two types of persistent stores? , 接近我需要的。不幸的是,只处理请求。我在 NSManagedObjectContext 类中没有看到类似于 NSFetchRequest 方法 setAffectedStores 的方法进行保存。

    最佳答案

    感谢 Ray Wenderlich转介到 Mic Pringle , Mic 提出了一个托管对象模型架构,通过它我能够在坚持我的目标的同时解决问题。解决方案的关键是利用抽象实体作为用户和种子实体的父实体。

    Managed Object Model

    使用此架构,可以创建分配给不同商店的两个配置:
    1) UserData - 位于用户文档目录中的 r/w 存储。

    UserData Configuration

    2) SeedData - 仅位于 App Bundle 中的商店。

    SeedData Configuration

    缺点是必须为种子数据实体维护记录 ID(因为配置之间不允许存在关系),但巨大的好处是可以对种子数据进行更改或添加,而不会影响用户的条目,也无需采用在这个问题的原始帖子的研究部分中讨论的任何繁琐的解决方案。

    关于sqlite - 将一个 ManagedObjectContext 和 PersistentStoreCoordinator 与两个存储一起使用时如何保存数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23665714/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com