核心数据置空规则何时更新关系



我拥有和想要什么:

我有一对多的关系a<--->>B(多对多部分已订购)。

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

问题描述:

因此,我遇到了与这个问题"核心数据无效规则不起作用?"中所说的完全相同的问题:我删除了一个与a有关系的B,然后立即计算剩余的B的数量,a与之有关系,并且与以前相同。这个问题的公认答案是使用级联而不是无效,因为无效的作用是:

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

我认为这个答案有两个问题:

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

经过一点实验,我发现,如果我删除了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与B的关系在之前计数:3"。因此,无效删除规则确实可以按照我的意愿工作,但会有一点延迟。

问题:

  1. 我陈述的两个问题有效吗
  2. 为什么无效只在延迟后更新关系?延迟是什么?或者,在删除NSManagedObject后,关系会在什么时候更新
是的,你是对的。答案不正确。关于第二点。方法-deleteOdject并没有按预期删除对象,它只是将对象标记为已删除。要完成删除,您需要保存托管对象上下文,然后您会看到nullify规则按预期工作。如果您现在不想保存上下文,可以采用两种方法:
  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在运行循环结束时或执行-save:时自行执行-processPendingChanges,因此您会看到一些延迟。

希望能有所帮助。

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

最新更新