带线程的多上下文核心数据

时间:2013-10-29 18:20:30

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


更新:我认为问题是在保存子上下文时不会更新父上下文。不过,还需要帮助。


我尝试了很多多上下文(父子)核心数据的例子。

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

在不干扰应用程序流程的情况下(即删除了OperationQueue),我试图实现Parent-Child ManagedObjectContext关系,其中我使用了一个privateMOC,其concurrencyType为NSPrivateQueueConcurrencyType,其中包含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等错误。 NSValidationErrorKey错误,表示某些值为nil。 是不是tempMOC的变化没有进入mainMOC?我没有深入挖掘,但据我所知,它不应该是零。 可能是什么错误?请帮助。

UPDATE:我试图打印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;

2 个答案:

答案 0 :(得分:1)

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

我实例化了一些NSManagedObject类,修改了它们的一些属性,然后将它们插入到temp或child NSManagedObjectContext中。所有的属性都像你的情况一样好。

但是当我保存上下文并且更改被推送到父NSManagedObjectContext时,所有属性都被取消(就像你的情况一样)。

在仅使用一个NSManagedObjectContext时,我没有观察到此行为,并且我没有尝试使用较旧的NSManagedObjectContextDidSaveNotification模式。

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

答案 1 :(得分:0)

vshall,

如果您已经有背景插入MOC模式工作,为什么要尝试转移到父母MOC情况?它并不快。而且,根据我对您的实现的看法,您最终会阻止主线程。

使用父子MOC关系有很多充分的理由。其中大多数涉及创建临时或只读MOC。第二个大用例是让您的主要MOC成为私人并发MOC的子女。这种方式保存是“快速”并在后台线程上完成。根据我的经验,将背景插入主MOC的子并发MOC的速度较慢,导致UI口吃。

在回答您的问题时,您试图在嵌入式保存集完成之前访问项目。因此,您的数据已损坏,您将获得例外。

安德鲁