coredata学习总结(十三)

来源:互联网 发布:英雄连2 单位数据 编辑:程序博客网 时间:2024/05/17 21:41

Change Management

如果你的应用程序包含多个managed object context 并且你允许对象在多个context中被修改,你需要使得这些改变统一性。常见的情形是当应用程序正在从网络加载数据时,用户一边也在修改数据。

Multiple Contexts in One Application

任何同给定的managed object context相关联的对象图表都必须内部是一致的。如果你在一个应用程序中有多个managed object contexts,有可能每一个都包含这些代表相同记录的数据在持久化存储中。但是她们的内容却是不一致的。例如,在employee工程中,你可能有两个独立的窗口都来展示同样的employees,但是department不同而且managers不同。如下图,看manager关系是如何从lau变成weiss的。managed object context 1 依然代表了在磁盘上的数据,但是managed object context2改变了。

Figure 15-1Managed object contexts with mutually inconsistent data valuesimage: ../art/Change_Management_1.pdf

这些views间的不同之处必须被索引到并且在数据saved的时候要保证一致性。当一个managed object context被保存的时候,他的改变通过coordinator来push到持久化存储中。当第二个managed object context被存储时,冲突就会被发现。冲突如何被解决取决于你是如何配置context的。

Conflict Detection and Optimistic Locking

当core data从持久化存储中fetch对象时,他为其状态拍摄了快照。一个快照就是一个对象持久化属性的dictionary-他所有的属性和每一个对象的global ids。当框架做存储操作时,会将每一个可编辑的快照对象值同当前在持久化存储中的对应值做比较。

  • 如果值是相同的,因为object被fetch后存储中的值没有改变,因此save正常进行。作为save操作的一部分,快照值被更新来匹配saved数据。
  • 如果值是不同的,由于对象被fetched或者上次被save过,那么存储就发生了变化。冲突必须被解决。
Choosing a Merge Policy

默认的行为被NSErrorMergePolicy属性来定义。如果有任何的merge冲突,这个策略会导致存储失败。一个包含conflictList 关键字的userinfo字典错误通过save方法返回。对应的值是包含冲突记录的数组。你利用这个数组来通知用户他们尝试保存的值和当前存储的值的不同。那么用户必须解决这些冲突。(通过refetching对象从而更新快照)

NSErrorMergePolicy是产生错误的唯一策略。其它的策略NSMergeByPropertyStoreTrumpMergePolicy,NSMergeByPropertyObjectTrumpMergePolicy,和NSOverwriteMergePolicy 允许将被编辑对象的状态同在存储中的对象状态merge后进行存储。NSRollbackMergePolicy 会忽略处于冲突中的内存中的状态改变的对象。并且使用持久化存储中的对象状态。

Automatic Snapshot Management

一个应用程序如果fetch几百行数据就可以创建一个大的快照的缓存。因此,如果足够的fetch被执行了,基于core data的应用程序可以包含所有在内存中的存储内容。明显的,为了防止这种情况,快照必须可被管理。

snapshot reference counting.负责清理快照。这个机制追踪同特定快照相关联的managed对象。-也就是,包含特定快照的managed objects。当没有同特定快照相关联的managed object时,core data就会自动打破到快照的引用并且从内存中被移除。

Synchronizing Changes Between Contexts

如果应用程序中使用了多个context,core data不会自动将一个context的改变通知给其它的对象。通常的,这是因为一个context允许你对一个独立的object做出改变,而且你可以忽略这些改变从二不作用于其它的contexts。如果你需要在不同的context中间同步改变的话,如果管理改变取决于你想在第二个context中的用户可见的形式,和在第二个context中的对象的状态。

Registering with NSNotificationCenter

假设一个应用程序有两个managed object contexts和一个单独的持久化存储coordinator。如果一个用户在第一个context(moc1)中删除了一个对象,你可能需要通知第二个context(moc2)有对象被删除了。moc1会自动postNSManagedObjectContextDidSaveNotificationnotification通知。这个通知不仅仅包含被删除的对象,也包含改变的对象。

Choosing a Synchronization Strategy

当决定如何处理删除通知时,可以考虑如下:

  • 在第二个context中存在哪些改变?
  • 被删除的对象实例在第二个context中有改变吗?
  • 第二个context中的改变能被undone吗?

The following three strategies are presented in order of increasing complexity.

  1. The object itself has been deleted in moc1 but has not changed inmoc2. In that situation you do not have to worry about undo, and you can just delete the object inmoc2. The next time moc2 saves, the framework will notice that you are trying to redelete an object, ignore the optimistic locking warning, and continue without error.

  2. If you do not care about the contents of moc2, you can simply reset it (using reset) and refetch any data you need after the reset. This will reset the undo stack as well, and the deleted object is now gone. The only issue here is determining what data to refetch. Do this before you reset by collecting the IDs (objectID) of the managed objects you still need and using those to reload once the reset has happened. You must exclude the deleted IDs, and it is best to create fetch requests withIN predicates to ensure faults will be fulfilled for deleted IDs.

  3. If the object has changed in moc2, but you do not care about undo, your strategy depends on what it means for the semantics of your application. If the object that was deleted inmoc1 has changes in moc2, should it be deleted frommoc2 as well? Or should it be resurrected and the changes saved? What happens if the original deletion triggered a cascade delete for objects that have not been faulted intomoc2? What if the object was deleted as part of a cascade delete?

    There are two workable options:

    • Simply discard the changes by deleting the object in the moc that is receiving the notification.

    • Alternatively, if the object is standalone, set the merge policy on the context toNSOverwriteMergePolicy. This policy will cause the changes in the second context to overwrite the delete in the database.

      it will cause all changes in moc2 to overwrite any changes made inmoc1.

The preceding solutions are least likely to leave your object graph in an unsustainable state as a result of something you missed. If you find your application hitting merge issues that you are not able to resolve, this generally indicates an issue with the application’s architecture.

0 0
原创粉丝点击