42

介绍

我的 iOS 项目附带了一个重约 160MB 的 SQLite 格式的 Core Data 持久存储。那里有大量的分组信息,用户应该能够在其中标记收藏夹。为此,我需要(至少部分)数据库具有写入功能。但当然,应用程序包中的持久存储在设计上是只读的。

如果您希望商店具有读写能力,您应该将其复制到,例如应用程序的文档文件夹。我不想这样做,因为那样应用程序的大小将是原来的两倍,而该数据库的主要部分无论如何都是只读的。那将是资源的浪费。

NSPersistentStoreCoordinator 的多个持久存储

这就是为什么我想使用两个持久存储。第一个是捆绑包中的大的,第二个可能是文档文件夹中的一个小的,存储与大商店有关系的特殊“最喜欢的”实体。

我知道在这方面有一些可能,但我找不到具体细节。如果您还有多个对象模型,是否应该只使用多个商店?一个对象模型可以“分布”在两个持久存储上吗?浏览核心数据编程文档时,我找不到任何关于如何设置的真正参考。Marcus Zarra 的书似乎也没有深入探讨这个话题:

可以向 NSPersistentStoreCoordinator 添加多个 NSPersistentStore,这在处理拆分为多个文件的数据时非常有用。但是,在我们的示例中,我们只有一个文件。(Marcus Zarra:“Core Data - Apple 用于在 Mac OS X 上持久化数据的 API”,第 71 页

问题

谁能告诉我我的想法是否可以通过 Core Data 和多个持久存储实现?您能否提供有关如何实现这一目标的提示?也非常感谢处理该主题的在线/离线资源。

4

3 回答 3

47

答案是肯定的。@Caleb 指向正确的资源,但让它工作仍然很尴尬。我想我会在这里放一份简历:

要让两个NSPersistentStore实例共享同一个模型,您必须向模型添加一个配置,该配置是实体的字符串命名子集:

模型配置

在模型中,为属于第二个商店的实体添加一个获取的属性(NSFetchedPropertyDescription用于谷歌搜索)。这是一个非常简单的存储过程,它可能看起来像这样:

获取的属性的 NSPredicate 格式

然后,当您将存储添加到持久存储协调器时,您使用字符串作为configuration参数(有关选项的更多信息here):

[persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 
                                          configuration:@"ModifyInBackground" 
                                                    URL:storeURL1
                                                options:options
                                                  error:&error]

[persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 
                                          configuration:@"ModifyInMain"
                                                    URL:storeURL2 
                                                options:options 
                                                  error:&error]

最后,当您想从商店 B 中的实体获取到商店 A 中的实体时,您只需访问它即可触发 fetched 属性,就像触发故障一样。

注意:一个获取的属性总是返回一个 NSArray,因为你为建立链接而编写的谓词可能有多个结果。如果您只想获得一个实体,您可以在NSManagedObject子类的包装方法中放置类似的内容:

Wallpaper *recordedWallpaper = [record.wallpaper lastObject];
于 2012-11-17T23:26:24.873 回答
5

是的,您可以为单个模型使用多个商店,但您不能在不同商店中的对象之间创建关系。查找核心数据编程指南中的跨存储关系部分,它基本上说明了这一点,并且如果您需要将一个存储中的对象与另一个存储中的对象相关联,则建议使用获取的属性。

于 2011-03-08T12:13:28.587 回答
1

一个想法:您可能希望完全创建不同的商店,并为每个商店创建不同的持久商店协调器。然后为每个模型部分创建不同的托管对象上下文。所以让我们说,我有一个包含 3 个实体的模型:学生、学院和课程。假设我想在 store1 中存储学生和学院实体,在 Store2 中存储课程,我将有 2 组 managedObjectContext、持久存储和持久协调器。现在鉴于我们不能有任何跨商店关系,在一个上下文中的修改不会影响另一个上下文。您不必创建不同的模型或将它们与商店相关联等。

于 2011-04-13T09:01:20.687 回答