核心数据栈的多个实例

时间:2014-08-21 17:04:18

标签: ios objective-c core-data swift nsmanagedobjectcontext

我创建了一个我在使用iOS开发时使用的锅炉板CoreDataStack。它与apple在appDelegate中提供的代码几乎相同。我有一个关于如何将其传递给每个视图的问题。根据我的阅读,两个主要选项是:

  1. 将上下文传递给需要它的每个类/视图。这似乎是合乎逻辑的,但它可以创建许多额外的代码,特别是如果你需要通过多个视图传递上下文而不需要使用它只是为了将它带到视图中。

  2. 每次需要时引用appDelegate的上下文。大多数人认为这是糟糕的编程,但它可以导致比选项1少得多的代码。

  3. 为什么我不能在每次需要时创建一个新堆栈?我使用我的CoreDataStack类在appDelegate中创建一个堆栈。为什么我不能在另一个类/视图中再次创建它?我理解我需要确保它是在正确的线程中创建的,但我确信我可以找到一种方法来做到这一点。

3 个答案:

答案 0 :(得分:0)

大多数时候,我只是通过AppDelegate访问它。 CoreData堆栈是我使用AppDelegate访问某些东西的一次,否则我就像瘟疫一样避免它!如果你不想这样做,你可以使用一个单独的CoreDataStack单例。无论哪种方式,你都拥有一切。

每次使用时都不重新创建核心数据堆栈的原因是ManagedObjectContext的每个实例都会分别跟踪对象。如果您创建一个新对象并在单独的类中使用它操作对象,则您的对象可能彼此不同步,因为每个MOC都可以拥有它自己对ManagedObject的内部引用。在MOC上调用-save并不能保证对象立即写入数据存储区,因此如果对两个不同类中具有两个不同MOC的对象进行更改,则可能会遇到对象冲突。必须合并。

答案 1 :(得分:0)

我通常删除AppDelegate核心数据堆栈并将其移动到自己的类中。我使用单例模式来管理我的核心数据堆栈,并在堆栈中也有一些辅助方法。保持您的应用程序代表尽可能干净。 Apple的样本是一个快速入门的例子。

我有一个方便的功能 - (NSManagedObject *)findByEntityName:(NSString *)entityName searchPredicate:(NSPredicate *)searchPredicate;

答案 2 :(得分:0)

您当然可以按需创建新的托管对象上下文。为此,您需要创建一个新的上下文并设置它的父上下文或持久性存储协调器。但是,您需要注意何时保存对这些上下文的更改,以及核心数据堆栈的其他用户是否能够查看未保存的更改。如果多个上下文可能会更改相同的实体,您可能还需要处理合并冲突。

这与按需重新创建整个Core Data堆栈不同,您至少需要一个共享持久性存储协调器来检测并响应此类冲突,而不是仅通过写入持久性存储来任意解析它们。

我个人的偏好是使用依赖注入容器向控制器提供上下文。这给了我一个位置,我可以在其中更改创建上下文的默认策略(每次创建一个共同父项的新子项或共享一个默认上下文),但也允许我根据具体情况覆盖该策略,如果我想要一个用于接收子上下文的特定控制器(也许所有这些更改都可以被丢弃,或者如果一个案例需要不同的并发类型)。