【问题标题】:Using NSManagedObject subclasses to transport persistent and non persistent data使用 NSManagedObject 子类传输持久性和非持久性数据
【发布时间】:2013-04-03 23:23:45
【问题描述】:

我对如何使用一些核心数据的 NSManagedObject 子类来处理持久数据和非持久数据有一些想法。

假设您有一个食谱应用程序,其中显示了来自 CoreData 的您自己的食谱列表,并且在同一个应用程序中您也可以搜索其他用户的食谱。 这些其他用户的配方当然来自 API,我们不想将它们保存到核心数据中。 但是我们想要的是我们的配方细节视图控制器,无论是给定一个持久配方还是一个非持久配方,都可以发挥相同的作用。 我自然认为我们应该在我们的数据周围使用相同的对象包装器,并让我们的视图控制器对数据的来源视而不见。

问题是 NSManagedObject 子类不能手动初始化,必须插入到上下文中。这对我们其他用户的食谱不利。另一方面,对于我们自己的食谱,我们需要将这些对象插入到上下文中。

我有几个解决方案,但我真的很想看看你们对这个问题的看法。

您是否会说这是一些实现问题,应该通过将两个数据对象包装到一个对象中来解决?例如,通过覆盖所有 getter 和 setter 来处理 coredata 对象和 NSDictionary 对象?

或者它是一个架构问题,您可以通过嵌套 NSManagedContext 或使用多个持久存储(一个在内存中,另一个在 Sqlite)来解决它?

【问题讨论】:

    标签: ios core-data nsmanagedobject nsmanagedobjectcontext


    【解决方案1】:

    实际上,您可以创建 NSManagedObject 实例,而无需将它们插入上下文中。只需将 nil 作为托管对象上下文参数传递。执行以下操作:

    NSEntityDescription *myRecipeEntity = [NSEntityDescription entityForName:@"MyRecipeEntity" inManagedObjectContext:[self managedObjectContext]];
    MyRecipeClass *recipe = [[MyRecipeClass alloc] initWithEntity:myRecipeEntity insertIntoManagedObjectContext:nil]];
    

    现在您有了一个不在任何上下文中的配方实例。

    如果您稍后想将其添加到上下文中:

    [[self managedObjectContext] insertObject:recipe];
    

    如果不想插入,就扔掉吧。

    【讨论】:

    • 据我所知,您不能在未插入上下文的对象之间建立关系。
    • 当然。但这并不总是重要的。
    • 谢谢,这可能是一个解决方案...我会尝试并让你们知道
    • 嘿,这似乎确实有效,而且在我的情况下,您是对的,没有临时对象的关系并不重要。顺便说一句 initWithEntity:insertIntoManagedObjectContext: 似乎是一个实例方法而不是类方法,并且可以用作任何其他 init 方法。非常感谢我现在接受这个答案;)
    • 我在 OSX 上为此编写了一个演示,但遇到了无法保存属性的问题(请参阅 github.com/seltzered/CoreDataMagicalRecordTempObjectsDemo)。从我的结果来看,使用子上下文似乎是一种更安全的方法,正如在类似问题中所建议的那样 - stackoverflow.com/a/14494126/314780
    【解决方案2】:

    我可能只使用一个您从不保存的单独上下文,这似乎是最简单的方法。

    【讨论】:

      【解决方案3】:

      模型配置 - 内存存储和 sqlite 支持的存储。

      我会认真考虑使用模型配置和两种持久存储类型: 内存和 sqlite 支持。

      但这也意味着您必须为可下载的数据创建单独的实体,这会否定您可以让一些配方持久化和一些临时性的想法,而它们都是配方。此外,您不能在不同持久存储中的实体之间建立关系。您将放弃反向关系的好处,并且必须使用获取的属性来模仿这一点。

      总而言之,这是一个可行的选择,但也有一些缺点。

      隔离的托管对象上下文

      使用单独的托管对象上下文的最大优势是您可以将相同的配方实体用于持久数据和临时数据。您必须避免保存临时上下文,并且必须从持久存储中引入所有更改,或者从具有您保存的数据的其他上下文中合并。

      这种替代方案的挑战在于,您必须在此隔离上下文之上构建大部分 UI 以供阅读,但您所做的所有永久性更改都需要保存到主上下文并通过合并到隔离上下文中传播回来.这可能会引入一些棘手的情况,但我认为这是可行的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-04
        • 2011-04-21
        • 2015-12-23
        • 1970-01-01
        相关资源
        最近更新 更多