【问题标题】:Multi Context CoreData with Threads带线程的多上下文 CoreData
【发布时间】:2013-11-09 01:51:56
【问题描述】:

更新:我想问题是在保存子上下文时父上下文没有更新。不过,需要帮助。


我已经尝试了许多多上下文(父子)核心数据的示例。

以前我的应用程序使用传统的数据存储方式,即我使用了 OperationQueue,在其中我从服务器获取数据并使用 MOC 保存到数据库,并在保存时向 mainMOC 发送通知以 mergeChanges:NSManagedObjectContextDidSaveNotification。

在不干扰应用程序流程(即删除 OperationQueue)的情况下,我尝试实现父子 ManagedObjectContext 关系,其中我使用 concurrencyType 为 NSPrivateQueueConcurrencyType 的 privateMOC,它有一个 persistantStoreCoordinator,而 mainMOC 的 concurrenyType 为NSMainQueueConcurrencyType 是 privateMOC 的孩子。在队列中,我有一个 tempMOC,其 concurrencyType 为 NSPrivateQueueConcurrencyType,它是 mainMOC 的子对象。

在保存时,我将三个 MOC 的 performBlock 嵌套为 -

[tempMOC performBlock:^{
        if (![tempMOC save:&error]) {
            NSLog(@"Error : %@",error);
        }
        [mainMOC performBlock:^{
            if (![mainMOC save:&error]) {
                NSLog(@"Error : %@",error);
            }
            [privateMOC performBlock:^{
                if (![privateMOC save:&error]) {
                    NSLog(@"Error : %@",error);
                }
            }];
        }];
    }];

在 mainMOC 尝试保存时,我收到类似 CoreData 1560 和 1570 的错误。 NSValidationErrorKeyerror 它说某个值是nil。 是不是 tempMOC 的变化不会转到 mainMOC ?我没有深入研究,但据我所知,它不应该是零。 可能是什么错误?请帮忙。

更新:我尝试打印 tempMOC 的对象,我看到了正确的值,例如:

<Element_Name: 0xc0b59c0> (entity: Element_Name; id: 0xc07ca90 <x-coredata:///Element_Name/t2DCD57A8-4C1A-4AF7-A10E-5B9603E2BB8730> ; data: {
    tag1 = nil;
    tag2 = 3430065;
    tag3 = 600;
    tag4 = N;
    tag5 = "2013-10-29 00:00:00 +0000";
    tag6 = nil;
    tag7 = 327842701;
    relation = "0xbf1f760 <x-coredata://87C54A94-701E-4108-826E-4D98A53380F9/Relation/p1>";
    tag8 = "Some_Value";

我试图打印 mainMOC 的对象,我看到 nil 值而不是像这样的数据:

<Element_Name: 0xbd47a50> (entity: Element_name; id: 0xc0b14b0 <x-coredata:///Element_Name/t2DCD57A8-4C1A-4AF7-A10E-5B9603E2BB8740> ; data: {
    tag1 = nil;
    tag2 = nil;
    tag3 = 0;
    tag4 = nil;
    tag5 = nil;
    tag6 = nil;
    tag7 = nil;
    relation = "0xbd586c0 <x-coredata://87C54A94-701E-4108-826E-4D98A53380F9/relation/p1>";
    tag8 = nil;

【问题讨论】:

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


    【解决方案1】:

    我刚刚遇到了同样的问题并找到了解决方案。如果没有您的其余代码,我无法保证这会解决您的问题,但它确实解决了我的问题。

    我正在实例化一些 NSManagedObject 类,修改它们的一些属性,然后将它们插入到临时或子 NSManagedObjectContext 中。所有属性都显示得很好,就像你的情况一样。

    但是当我保存该上下文并将更改推送到父级 NSManagedObjectContext 时,所有属性都无效(就像您的情况一样)。

    我在只使用一个NSManagedObjectContext 时没有观察到这种行为,我也没有尝试过旧的NSManagedObjectContextDidSaveNotification 模式。

    解决方案当然是在初始化之后和任何属性分配完成之前将NSManagedObject 添加到上下文中。

    【讨论】:

      【解决方案2】:

      应该,

      如果你已经有一个背景插入 MOC 模式工作,你为什么要尝试转移到父子 MOC 情况?它并不快。而且,从我对您的实现的了解来看,您最终会阻塞主线程。

      使用父子 MOC 关系有很多很好的理由。其中大多数涉及创建临时或只读 MOC。第二个大用例是让您的主 MOC 成为私有并发 MOC 的子级。这样保存是“快速的”并且在后台线程上完成。根据我的经验,将后台插入到主 MOC 的子并发 MOC 中速度较慢,并且会导致 UI 卡顿。

      在回答您的问题时,您正试图在您的嵌入式保存完成之前访问项目。因此,您的数据已损坏并且您会遇到异常。

      安德鲁

      【讨论】:

      • 当主MOC通过notification-NSManagedObjectContextDidSaveNotification更新时,后台插入MOC会挂起UI。经过一番谷歌搜索,我发现与传统 MOC 相比,父子 MOC 不会挂 UX
      • 我无法确认代码是否在保存完成之前尝试访问该集合,因为我也尝试将保存嵌入 performBlockAndWait 中。
      • vshall,由于您没有列出您认为父子 MOC 更快且不会挂起 UI 的原因,因此我无法解决您的主张。根据我的经验,情况并非如此。至于您的情况,我认为您正在尝试在保存数据之前访问数据。您可能可以通过延迟阅读代码来测试它是否如此。安德鲁
      • adonoho,这里有一些链接:slideshare.net/xzolian/…stackoverflow.com/questions/8171869/… 以及一些博客说父子上下文比传统的 NSManagedObjectContextDidSaveNotification 方式更好。此外,根据父子上下文,我将子项保存在嵌套的 performBlock.Still 中,然后将父项立即保存。父级获取 nil 数据。我尝试评论数据获取并仅​​保存数据。
      猜你喜欢
      • 1970-01-01
      • 2013-09-19
      • 1970-01-01
      • 1970-01-01
      • 2015-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多