我真的不明白你的问题。如果你公开了一个继承自 NSManagedObject 的类,那么该类的用户就会有这个强制,以及伴随的问题。
如果您将您的类公开为一个组合,则托管对象的详细信息就在该类中,并且这些详细信息很容易被隐藏。
您当然可以根据需要创建/销毁 MOC,它们非常便宜。但是,这似乎并不是超级有益的。
我建议保留一个用于界面的托管对象上下文。您提到担心多个线程调用到 MOC。这是一个有效的问题,但通过使用带有 NSPrivateQueueConcurrencyType 的 MOC 可以轻松有效地克服。
然后,每当您需要获取对象时,您只需执行
[moc performBlockAndWait:^{
// Fetch the object from the MOC
}];
调用同步版本时要小心,因为您有可能出现死锁。
或者,您仍然可以使用为每次提取创建唯一上下文的选项...
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
moc.parentContext = myPrivateQueueContext;
// Now, you can fetch from this MOC, and do what you want with the object
// and when you are done, you just let the MOC dealloc.
您可能想查看 NSFetchRequest 的选项,以及 MOC 本身的设置,特别是
refreshObject:mergeChanges:
retainsRegisteredObjects
如果您告诉 myPrivateQueueContext 保留对象,它会将它们保留在其本地 MOC 中。然后,当您执行 fetch 时,您可以告诉 fetch 更喜欢 MOC 中的缓存版本,它甚至永远不会进入磁盘。
如果您存储托管对象的 objectID,您可以获得更多优势,并且只需调用 objectRegisteredForID: 即可查找已注册的对象。无论谁否决了答案,然后您可以手动清理缓存,因此如果需要,它不会变得太大。
或者,您可以调用 existingObjectWithID:error: 永远不会返回错误。结果将始终是已实现的对象或 nil。
无论如何,我认为您想做的事情可以通过多种方式轻松解决。不过,我会提醒您,不要过度设计您的解决方案。
找出你想要公开的接口,并实现它。如果您以后发现性能问题,请在那时处理它们。
** 编辑 **
专门针对 Danra 的评论(以及对答案投反对票的人)。我从未打算让您直接从私人 MOC 访问数据。如果要访问私有 MOC,请使用 performBlock。
但是,您可以根据需要创建任意数量的子...任何并发类型,并根据您的意愿使用它们。当他们需要与数据库对话时,他们将直接与父级对话(在适当的上下文中)。
我所说的一切都没有建议您对私有 MOC 做任何事情,但调用 performBlock 或使其成为另一个 MOC 的父级。