有没有办法只清除核心数据中某些NSMangedObjects的变量值?

时间:2013-04-26 21:58:52

标签: ios core-data nsmanagedobject nsmanagedobjectcontext

我的问题是通过将此更新发布到服务器来协调核心数据对对象(包括关系)变化的意识。

例如:

  1. 假设我有一个具有2对多关系的托管对象。我在服务器上获取两个关系中包含的对象。对于关系A,服务器返回1对象所属的。对于关系B,服务器返回那里没有。因此,对于A,我将JSON响应解析为NSManagedObject并将其插入到关系A中。对于B,我什么都不做。此时,如果我在rel A中唯一的对象中查询-changedValues,它会说rel的逆是为它改变了,因为它被插入到rel A.因为我想要从服务器获取的对象代表"默认"或者"最后一次承诺" state,我发出一个核心数据上下文保存,此时,changedValues不再反映插入。到目前为止一切顺利。

  2. 接下来,我在本地(不是通过从服务器获取),创建2个对象。我在rel A中插入一个(它现在有2个对象),在rel B上插入另一个(现在有1个对象)。

  3. 此时,我希望整个系统能够意识到rel A中的第一个对象是从那里开始的,因此不需要对它进行任何操作。 A中的第二个是新插入,因此它需要发布到服务器,而第三个对象是rel B中唯一的一个,也是一个新的插入,所以需要一个POST。
  4. 我尝试通过查询相应关系目标实体的所有对象的上下文来尝试接近这一点,该实体具有-valueChanged的值,而该值是在适当的关系之后命名的键[反向]。对于具有这些关系的某个对象x,当前状态为:

    x.relA = <NSSet: obj1, obj2>
    x.relB = <NSSet: obj3>
    

    ,查询基本上是

    // For each relationship:
    NSError *error = nil;
            NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:mapping.entityName];
            NSArray *fetchResult = [self.context executeFetchRequest:fetchRequest error:&error];
        NSArray *deletedObjects = [fetchResult filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
            id relationship = [evaluatedObject changedValues][<inverseOfRelationship>];
            return relationship && ![relationship containsObject:x];
        }]];
    
        NSArray *insertedObjects = [fetchResult filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
            id relationship = [evaluatedObject changedValues][<inverseOfRelationship>];
            return relationship && [relationship containsObject:x];
        }]];
    

    原则上这是有效的。但问题是,我首先评估rel A.我得到删除和插入的列表(不计算默认情况下已存在的内容。)并为服务器发出适当的DELETE和POST以获得这两个数组。到现在为止还挺好。但是,现在我发出一个coredata上下文保存,以便这种关系当前状态成为&#34;默认&#34;州。好。确定...但是...保存也消除了rel B中obj3的更改。因此,如果我现在尝试使用上面的代码查询该关系,obj3s&#39; changedValues不会报告任何值,因为理论上obj3的rel B成员资格是默认值(自上次保存以来)。

    所以我需要一种方法来为某些对象做一个选择性上下文保存(我认为这是不可能的,因为这是&#34;上下文&#34;保存而不是对象保存),或者某种方式例如,有选择地清除我已经用服务器处理过的对象的已更改的值。

    另一种方法是在ManagedObjects中插入额外的更新/删除标志,并通过我自己的代码手动处理这些标志。似乎可行但有点贫民窟,因为它本质上是重新利用了有关上下文的managedObjects已经存在的标志。

    有什么想法或想法吗?

1 个答案:

答案 0 :(得分:0)

您可以从iOS5及更高版本轻松完成此操作。

您可以在父子关系中创建多个上下文存储。保存子上下文时,它实际上会被推送到父上下文。因此,对于您的示例,您将有一个子上下文用于对RelA所做的更改,另一个子上下文用于对RelB所做的更改。

然后,您将在用于更改RelA的上下文中保存更改,然后保存父上下文。用于对RelB进行更改的上下文不会受此影响。

本文对如何编写代码进行了很好的解释:http://www.cocoanetics.com/2012/07/multi-context-coredata/