如何“告诉”父上下文必须删除和/或插入哪些托管对象?

Posted

技术标签:

【中文标题】如何“告诉”父上下文必须删除和/或插入哪些托管对象?【英文标题】:How to "tell" a parent context which managed objects it has to delete and/or insert? 【发布时间】:2015-09-27 17:50:34 【问题描述】:

我在主队列中有一个父 NSmanagedObjectContext,在私有队列中有一个子 NSManagedObjectContext。我将父上下文中的一组托管对象传递给它的子对象。然后,子上下文从其父上下文中获得托管对象,然后插入新的托管对象。我在私有队列中对子上下文中的所有托管对象进行了一些处理,来自父对象的对象和它自己的新对象,在进程结束时,我需要告诉父对象:

需要删除它的哪些托管对象 它的哪些托管对象需要替换为子中的新托管对象 子项中的哪些托管对象需要插入到父项中

是否可以通过上下文之间的父/子关系来做到这一点?即使它们属于不同的队列?还是说父子关系只适合对某些托管对象的属性进行更改,而不适合托管对象的删除和插入?

如果无法通过父/子关系管理此场景,应该采用什么方法?

提前致谢

编辑: 我发现的示例只是使用子上下文来编辑父级的托管对象,然后在编辑结束时将更改应用于父级。所以我不确定是否可以使用子上下文在父上下文中删除或插入对象。

【问题讨论】:

【参考方案1】:

当子上下文调用save() 时,更改被推送到父上下文。这意味着,父上下文的整个对象图都会更新以反映子上下文的状态。

因此,您无需执行任何操作。删除的对象会消失,添加的对象会在那里,编辑的对象会更新。

【讨论】:

谢谢。那么,有没有必要设置合并策略呢?我真的找到了一些使用这种设置的例子...... 正确 - 大多数情况下无需设置合并策略。根据您的描述,我假设主上下文在子上下文执行其工作时不会更改相同的对象。因此,不需要合并。 实际上它似乎是这样工作的,非常感谢!【参考方案2】:

这是一个代码 sn-p(缺少一些块),它执行基于子级的删除,然后将其传递给父级。

[childContext performBlock:^
    // query array of messages

    // LOTS OF CODE

    // Loop through them and delete each message


    // Loop through each message
    for (id emptyMessage in emptyMessages) 

        i++;
        // Work in ContextBlocks...
        //            [childContext performBlock:^

        __block AHRSMessage *msg = (AHRSMessage *) [childContext objectWithID:emptyMessage];

        [childContext deleteObject:msg];


        if (i % modFactor == 0) 
            self.percentDone = i / totalRecords;

            NSLog(@"%.1f Saving ...", self.percentDone * 100);


            NSError *error;
            if (![childContext save:&error]) 
                NSLog(@"\n error => %@ \n", [error localizedDescription]);
                NSLog(@" error => %@ ", [error userInfo]);
                [NSException raise:@"Database Write Error" format:@"%@ %@", [error localizedDescription], [error userInfo]];

                //                    abort();
            

            [parentContext performBlock:^
                NSError *errrror;
                if (![parentContext save:&errrror]) 
                    NSLog(@"\n error => %@ \n", [error localizedDescription]);
                    NSLog(@" error => %@ ", [error userInfo]);
                    [NSException raise:@"Database Write Error" format:@"%@ %@", [error localizedDescription], [error userInfo]];

                    //                        abort();
                
            ];
        

        //            ];

    

子存档将其写入内存,要真正写入磁盘,您必须调用父存档。如您所见,我一个接一个地做 - 但这不是必需的。

【讨论】:

谢谢。所以...不需要设置合并策略或做任何其他事情?只是保存孩子会更新父母的变化吗? 我不能肯定地说 - 我还没有遇到过我需要一个的情况。

以上是关于如何“告诉”父上下文必须删除和/或插入哪些托管对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何安全地删除未保存的托管对象?

从托管对象上下文中删除后使用保留的 NSManagedObject 是不是安全?

合并托管对象上下文的方法

核心数据:父/子托管对象上下文是不是适合更新一组多个对象?

如何删除子托管对象上下文中的临时对象?

NSFetchedResultsController 在托管对象被修改时通知其委托删除更改,并且从不通知插入或更新