10

我拥有和想要的:

我有一个一对多的关系 A <--->> B (对多部分是有序的)。

  • 删除 A 时,与 A 有关系的所有 B 也应删除,因此 A 与 B 的关系的删除规则设置为级联-> 工作正常
  • 删除 B 时,只应清除与 A 的关系,因此 B 与 A 的关系的删除规则设置为无效-> 不起作用(仅在延迟后)

问题描述:

所以我遇到了与这个问题“核心数据无效规则不起作用?”中所述完全相同的问题。:我删除了一个与 A 有关系的 B,然后立即计算剩余 B 的数量,与 A 有关系,它和以前一样。该问题中接受的答案是使用 cascade 而不是 nullify ,因为 nullify 的作用是:

当对象被删除时,Nullify 将指针设置为 null。如果你有一个指针数组,它不会删除它,它只是将它设置为 null。

我看到这个答案有两个问题:

  1. 我很确定 cascade 在这种情况下是错误的规则,因为它在删除 B 时也会删除 A,这不是我想要实现的。(尽管如此,我还是尝试了它,结果是我所期望的:A 也被删除了)。
  2. 集合不能将 null 作为其元素之一,除非使用 NSNull 单例。所以我怀疑这就是无效规则的作用。

经过一番实验后,我发现,如果我删除 B 的一个实例,它会立即被删除,但与 A 的关系不会立即清除,而是会在一点延迟后清除:

// Method is called by pressing a button
-(void)removeLastBOfA:(A *)instanceOfA
{
    // Prints 4
    NSLog(@"fetch all b's count before:%d", [context fetchAllBs].count);
    // Prints 4
    NSLog(@"A's relation to B count before: %d", instanceOfA.relationToB.count);

    [context deleteObject:[instanceOfA.relationToB lastObject]];

    // Prints 3
    NSLog(@"fetch all b's count after:%d", [context fetchAllBs].count);
    // Prints 4, but should be 3. Last Object of A's relationToB is still the object that was deleted
    NSLog(@"A's relation to B count after: %d", instanceOfA.relationToB.count);

}

现在,当按下按钮再次调用上面的方法而不做任何事情时,突然关系被更新并打印“A's relationship to B count before: 3 ”。因此,无效删除规则确实可以按我的意愿工作,但会有一点延迟。

问题:

  1. 我说的两个问题有效吗?
  2. 为什么 nullify 只在延迟后更新关系,延迟是什么?或者在删除 NSManagedObject 后关系在什么时候更新?
4

2 回答 2

16

是的你是对的。答案是不正确的。关于第二点。方法 -deleteOdject 不会像您预期的那样删除对象,它只是将对象标记为已删除。要完成删除,您需要保存托管对象上下文,然后您将看到无效规则按预期工作。如果您此时不想保存上下文,可以采用两种方法:

  1. 显式删除关系:

    NSManagedObject* objectToDelete = [instanceOfA.relationToB lastObject];
    [context deleteObject:objectToDelete];
    NSMutableSet* relationships = [instanceOfA mutableSetValueForKey:@"relationToB"];
    [relationships removeObject:objectToDelete];
    
  2. 询问上下文以处理其未来的变化(这意味着计算由您的删除引起的变化):

    [context processPendingChanges];
    

在您的示例中:

[context deleteObject:[instanceOfA.relationToB lastObject]];
[context processPendingChanges];
// Prints 3
NSLog(@"fetch all b's count after:%d", [context fetchAllBs].count);
NSLog(@"A's relation to B count after: %d", instanceOfA.relationToB.count);

之后,您将看到预期的结果。

NSManagedObjectContext 会-processPendingChanges在运行循环结束或执行时自行执行-save:,这就是您看到一些延迟的原因。

希望能帮助到你。

于 2013-02-12T18:31:26.767 回答
0

完成对 Core Data 对象的更改后,您应该在托管对象上下文中调用save :。我想保存操作将更新所有关系。

于 2013-02-12T17:55:42.523 回答