1

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

例如:

  1. 假设我有一个具有 2 对多关系的托管对象。我在服务器上获取了两个关系中包含的对象。对于关系 A,服务器返回属于的 1 个对象。对于关系 B,服务器返回没​​有。因此,对于 A,我将 JSON 响应解析为 NSManagedObject 并将其插入到关系 A 中。对于 BI,什么也不做。此时,如果我要查询-changedValuesrel A 中的唯一对象,它会说 rel A 的逆发生了变化,因为它被插入到 rel A 中。因为我希望从服务器获取的对象表示“默认”或“最后提交”状态,我发出核心数据上下文保存,此时,changedValues 不再反映插入。到目前为止,一切都很好。

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

  3. 在这一点上,我希望整个系统都知道 rel A 中的第一个对象是从那里开始的,所以不需要做任何事情。A 中的第二个是新插入,因此需要将其发布到服务器,而 rel B 中唯一的第三个对象也是新插入,因此需要 POST。

我尝试通过查询适当关系目标实体的所有对象的上下文来解决这个问题,这些对象在以适当关系 ['s inverse 命名的键上具有 -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。我得到了删除和插入列表(不计算默认情况下已经存在的内容。)并为这 2 个数组向服务器发出适当的 DELETE 和 POST。到目前为止,一切都很好。但是,现在我发出 coredata 上下文保存,以便此关系当前状态变为“默认”状态。好的。当然...但是...保存也消除了 rel B 中 obj3 的更改。因此,如果我现在尝试使用上述代码查询该关系,则 obj3s 的 changedValues 将不会报告任何值,因为理论上 obj3 在 rel 中的成员身份B 是默认值(至少自上次保存以来)。

因此,我需要一种方法来仅对某些对象进行选择性上下文保存(我认为这是不可能的,因为这是“上下文”保存而不是对象保存),或者某种方法可以选择性地清除我的对象的 changedValues例如,已经使用服务器进行了处理。

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

有什么想法或想法吗?

4

1 回答 1

0

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

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

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

这篇文章很好地解释了如何编码:http: //www.cocoanetics.com/2012/07/multi-context-coredata/

于 2013-05-23T10:52:22.940 回答