【问题标题】:Can multiple (two) persistent stores be used with one object model, while maintaining relations from one to the other?多个(两个)持久存储可以与一个对象模型一起使用,同时保持一个到另一个的关系吗?
【发布时间】:2011-07-11 01:07:40
【问题描述】:

简介

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

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

NSPersistentStoreCoordinator 的多个持久存储

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

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

可以向 NSPersistentStoreCoordinator 添加多个 NSPersistentStore,这在处理拆分为多个文件的数据时非常有用。但是,在我们的示例中,我们只有一个文件。 (Marcus Zarra: "Core Data - Apple's API for Persisting Data on Mac OS X" page 71)

问题

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

【问题讨论】:

  • 我几乎想通了,请参阅stackoverflow.com/questions/10951844/… 示例项目
  • 你把它复杂化了。将 db 从包中复制到库文件夹并完成。
  • 考虑到你要么对一个 2 岁的问题发表评论,要么对这个问题发表 1 年的评论,你在这里不是很有建设性,@Rog。该应用程序的数据库现在接近 250 Megs,我认为它的用户只喜欢它一次。

标签: objective-c cocoa-touch core-data multiple-databases


【解决方案1】:

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

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

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

然后,当您将存储添加到持久存储协调器时,您使用字符串作为 configuration 参数(更多 info about the options 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];

【讨论】:

  • 你太棒了,一段代码和2张图比苹果的文档更能说明问题,谢谢!
  • 真正值得称赞的是 StackOverflow,但你还是让我很开心,谢谢!
  • 快速提问:在您发布的addPersistentStoreWithType:... 代码中,options 是什么?我使用其中一个模板构建了我的应用程序,它只是将nil 发送到options:。编辑:found it
  • developer.apple.com/LIBRARY/IOS/documentation/Cocoa/Reference/… 类似:NSDictionary *options = @{ NSMigratePersistentStoresAutomaticallyOption: @YES, NSInferMappingModelAutomaticallyOption: @YES };
【解决方案2】:

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

【讨论】:

  • 是的,这就是我最终所做的。问题是我希望能够使用 Xcode 建模工具对应用程序使用的数据有一个完整的概述。但我没有让它发挥作用。 :S
【解决方案3】:

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

【讨论】:

  • 很难从文档中获得一个工作示例。从描述来看,这是要走的路。但在这种情况下,模型是什么样的?您是否也使用两种不同的托管对象模型?还是一个模型有两个商店?
  • 改写:如何在模型编辑器中指定哪些实体属于哪个商店?真的是这样吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
  • 1970-01-01
  • 2019-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-22
相关资源
最近更新 更多