【问题标题】:NSManagedObjectContext confusionNSManagedObjectContext 混乱
【发布时间】:2012-02-06 03:39:03
【问题描述】:
我正在学习 CoreData。很明显,你进入的主要类之一是 NSManagedObjectContext。我不清楚这个的确切作用。从我读过的文章中,您似乎可以拥有多个 NSManagedObjectContexts。这是否意味着 NSManagedObjectContext 基本上是后端的副本?
当周围有多个不同的副本时,这将如何解决为一致的后端?
所以,基本上是两个问题:
NSManagedContext 是后端数据库的副本吗?
还有……
例如,假设我在上下文 A 中进行了更改,并在上下文 B 中进行了一些其他更改。然后我先在 A 上调用 save,然后在 B 上调用? B会占上风吗?
谢谢
【问题讨论】:
标签:
objective-c
ios
cocoa-touch
core-data
nsmanagedobjectcontext
【解决方案1】:
NSManagedObjectContext 不是后端数据库的副本。 documentation 将其描述为便签本
NSManagedObjectContext 的一个实例代表一个单一的“对象
空间”或应用程序中的便签本。它的主要职责是
管理托管对象的集合。这些对象形成一个组
表示内部一致视图的相关模型对象
一个或多个持久性存储。单个托管对象实例
存在于一个且仅一个上下文中,但存在多个对象的副本
可以存在于不同的上下文中。因此对象唯一性的范围是
特定的上下文。
NSManagedObjectContext 只是一个临时位置,用于以事务方式对托管对象进行更改。当您在上下文中更改对象时,它不会影响后端数据库,除非您保存上下文,并且您知道您可以拥有多个可以更改的上下文,这对concurrency 非常重要。
对于第 2 个问题,谁占上风的答案将取决于您为上下文设置的 merge policy 以及最后调用哪一个,即 B。以下是可以设置的合并策略,这些策略将影响第二个要保存的上下文。
NSErrorMergePolicyType
指定导致保存失败的策略
如果有任何合并冲突。
NSMergeByPropertyStoreTrumpMergePolicyType
指定一个策略
合并持久存储的对象版本之间的冲突
和当前的内存版本,优先考虑外部
变化。
NSMergeByPropertyObjectTrumpMergePolicyType
指定合并持久存储版本之间的冲突的策略
对象和当前内存中的版本,优先
内存中的变化。
NSOverwriteMergePolicyType
指定一个策略
为更改的对象覆盖持久存储中的状态
冲突。
NSRollbackMergePolicyType
指定一个策略
丢弃冲突对象的内存状态更改。
【解决方案2】:
NSManagedObjectContext 是数据模型的特定表示。每个上下文都维护自己的状态(例如上下文),因此一个上下文中的更改不会直接影响其他上下文。当您使用多个上下文时,您有责任通过在上下文将其更改保存到存储时合并更改来保持它们的一致性。
您的问题是关于这个过程的,也可能涉及合并冲突。每当您保存上下文时,它的更改都会提交到存储区,并使用合并策略来解决冲突。
当您保存上下文时,它将发布有关进度的各种通知。在您的情况下,如果[contextA save:&error] 成功,上下文将发布通知NSManagedObjectContextDidSaveNotification。当您有多个上下文时,您通常会观察此通知并调用:
[contextB mergeChangesFromContextDidSaveNotification:notification];
这会将contextA 上保存的更改合并到contextB。
编辑:删除了“线程安全”注释。 NSManagedObjectContext 不是线程安全的。