解决RestKit中的CoreData合并冲突,当一个上下文正在保存对象更新而另一个正在删除对象时
Posted
技术标签:
【中文标题】解决RestKit中的CoreData合并冲突,当一个上下文正在保存对象更新而另一个正在删除对象时【英文标题】:Resolving CoreData merge conflicts in RestKit, when a context is saving object updates while the other one is deleting the object 【发布时间】:2012-05-14 18:02:08 【问题描述】:假设我有一个名为 «Picture» 的 NSManagedObject,它是通过 RestKit 创建的。 我正在通过 NSOperation 上传实际的图片文件内容。 NSOperation 正在跟踪上传进度,并将其保存在 Picture 对象的 «progress» 属性中。
if(![self isCancelled])
Picture *pic = [Picture findFirstByAttribute:@"pictureId" withValue:self.pictureId];
if(![pic isDeleted])
pic.progress = [NSNumber numberWithFloat:progress];
[[RKObjectManager sharedManager].objectStore save:NULL];
在 NSFetchedResultsController 的帮助下,我的视图控制器正在显示图片对象列表。 上传效果很好,RestKit 正在执行线程安全并合并回主 NSManagedObjectContext,因此 UI 按预期显示上传进度。
现在想象一下,在上传图片时,用户按下了“取消”十字,这也应该删除图片对象。 在控制器中,我在 NSOperation 上调用了取消,这实际上在几毫秒内停止了运行操作,并且该对象从主线程上的 CoreData 中删除。
[uploadOperation cancel];
Picture *pic = [Picture findFirstByAttribute:@"pictureId" withValue:self.pictureId];
[pic deleteEntity];
[[RKObjectManager sharedManager].objectStore save:NULL];
跟踪显示我在 NSFetchedResultsControllerDelegate 上按预期获得了 NSFetchedResultsChangeDelete。然而,紧随其后的是 NSFetchedResultsChangeInsert 和 NSFetchedResultsChangeUpdate,因为 NSOperation 非常频繁地保存进度。 NSOperation 使用的 NSManagedObjectContext 似乎不同步。它不知道 Picture 对象被删除,调用 save: 导致插入和更新。
所以在我的 UI(和 DB)中,我的 Picture 对象在它应该被删除时仍然存在。
查看 RKManagedObjectStore,似乎合并是从后台线程 (NSOperation) 到主线程(我的视图控制器),但不是相反的方式。
解决此问题的最佳方法是什么?
【问题讨论】:
【参考方案1】:我认为你应该稍微改变一下应用程序的控制流程。在 NSOperation 仍在进行时删除主上下文中的对象听起来是个坏主意。您为什么不例如检查操作是否在 NSOperation
本身中被取消并使用其 MOC 从那里删除图像对象?这样,您只能在一个子 MOC 上进行写入。另一种选择,即在每次修改之前更新操作中的子 MOC,这违背了拥有单独上下文的目的。
考虑一下,可能有一些聪明的方法可以观察NSManagedObjectContextObjectsDidChangeNotification
并与适当的NSMergePolicy
合并,但话又说回来,我认为这对你的情况来说太过分了。我只是在同一个地方处理整个取消和删除。
【讨论】:
【参考方案2】:听起来是使用 Core Data Undo Manager 的完美场景。您可以在 over here 或 Apple 提供的 CoreDataBooks 示例中找到一个很好的示例。
【讨论】:
死链接“在这里”以上是关于解决RestKit中的CoreData合并冲突,当一个上下文正在保存对象更新而另一个正在删除对象时的主要内容,如果未能解决你的问题,请参考以下文章
当它们没有出现在 JSON 中时,Restkit 删除 Coredata 中的对象
CoreData + Restkit 当用户退出应用程序时要执行啥任务?
使用 RestKit 和 CoreData 同步修改对象的正确方法