保存单个CoreData实体(而不是整个上下文),同时保持NSFetchedResultController功能

9

哎呀,抱歉标题有点长。

我有一个单一的托管对象上下文,我在其中存储了来自两个不同位置的歌曲。我从手机上的持久化存储(使用Core Data)中获取一些歌曲,并从在线数据库中获取一些歌曲。这些歌曲都是相同的ManagedObject子类。我希望这两首歌都在一个上下文中,因为我希望它们都显示在与NSFetchedResultsController连接的表视图上。

问题出现在我想保存其中一首歌时。我不想将从在线数据库中拉取的所有歌曲都保存到手机上。我只想保存单独的一首歌曲,所以简单的[moc save]无法解决问题。另一个问题是,在保存单个歌曲后,我仍然希望在线拉取的歌曲位于上下文中(但再次强调,不会被保存)。我认为我有几个不同的选项:

1)是否可能将NSFetchedResults控制器连接到多个上下文?

2)我可以将从在线数据库中拉取的所有歌曲移动到一个单独的临时上下文中,在原始上下文中保存,然后再将所有歌曲移回。(参见:如何复制或移动来自一个上下文的NSManagedObject到另一个上下文中?

3)记住在线歌曲的所有键值对,从上下文中删除在线歌曲,保存原始上下文,在基于保存的键值对中重新插入所有在线歌曲。

4)我是个新手,可能忽略了更简单的方法。

谢谢!


你实际上想要保存什么?歌曲的位置还是实际的歌曲数据(文件)? - sosborn
2个回答

8
我认为最简单的方法是在持久性存储协调器中再添加一个NSPersistentStore。您可以将该存储设置为内存存储,并将所有“在线”结果存储在其中(临时存储)。您可以使用assignObject:toPersistentStore:指定新插入的对象应保存在哪个存储中。完成此操作后,您可以自由地保存,因为“保存”仅会在内存中进行,用于您的在线歌曲。
然后,当您想要将一首歌曲从在线集合移动到永久集合时,只需将其删除并重新插入,使用相同的方法将新对象分配给您的永久持久性存储。
这将允许您使用单个NSManagedObjectContext附加到您的NSPersistentStoreCoordinator,它将查看来自两个NSPersistentStore的对象。

苹果公司推广在类似场景中使用多个持久存储(例如应用程序附带的预设数据)。我认为,每当您有实体的持久性存储计划不同时,这都是一个好主意。 - rickster
1
如果您正在维护使用不同持久存储的实体之间的关系,请小心。根据我们在苹果公司的朋友所说:“您必须小心,不要从一个持久存储中的实例创建到另一个持久存储中的实例的关系,因为Core Data不支持此操作。如果您需要在不同的存储之间创建实体之间的关系,则通常使用获取属性。” https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdRelationships.html#//apple_ref/doc/uid/TP40001857-SW5 - NSTJ

5

Jesse的解决方案可以完美地工作。

但是,作为另一种选择,您可以简单地使用嵌套上下文,就像您为详细检查器所做的那样。

该上下文可以容纳所有“临时”项目,但由于它是您“保存”上下文的子级,因此所有获取都将正常工作。

NSManagedContext *tempContext = [[NSManagedContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
tempContext.parentContext = mainManagedObjectContext;

所有的保存内容都将被插入到mainManagedObjectContext中,并使用save:进行保存。所有的临时项目都将进入tempContext。

将您的获取结果控制器附加到tempContext上。

当您准备好摆脱临时项目时,只需将tempContext设置为nil即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接