Когда правило Core Data Nullify обновляет отношения?

Что мне нужно:

У меня есть отношение "один-ко-многим" A < --- → B (часть во многом упорядочена).

  • При удалении A все B с отношением к A также должны быть удалены, поэтому правило удаления для отношения A к B установлено в каскад → Прекрасно работает
  • При удалении B только отношение назад к A должно быть очищено, поэтому правило удаления для отношения B к A установлено в значение null → Не работает (только после задержки)

Описание проблемы:

Итак, у меня есть та же самая проблема, что и в этом вопросе Ядро Data Nullify не работает?: Я удаляю B, который имеет отношение к A и сразу после этого, я подсчитываю количество оставшихся B, что A имеет отношение с и оно такое же, как и раньше. Принятый ответ в этом вопросе состоял в том, чтобы использовать каскад вместо аннулирования, поскольку имеет значение null:

Nullify устанавливает указатель на нуль при удалении объекта. если ты иметь массив указателей, которые он не удаляет, он просто устанавливает нуль.

Я вижу 2 вопроса с этим ответом:

  • Я уверен, что каскад - это неправильное правило в этом случае, потому что он также удалит A при удалении B, чего я не хочу достичь. (Я все же пробовал, и результат был тем, что я ожидал: A также был удален).
  • Коллекция не может иметь нуль в качестве одного из своих элементов, кроме одного синтаксиса NSNull. Поэтому я сомневаюсь, что это то, что делает правило nullify.

После нескольких экспериментов я узнал, что если я удалю экземпляр B, он будет удален немедленно, но отношение к A не будет очищено немедленно, но только после небольшой задержки:

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

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

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

}

Теперь, когда вы нажимаете кнопку для вызова вышеописанного метода, не делая ничего между ними, внезапно обновляется связь и "Отпечаток отношения к счету B до: 3". Поэтому правило nullify delete работает, как я хочу, но с небольшой задержкой.

Вопросы:

  • Являются ли 2 вопроса, которые я изложил?
  • Почему аннулирование только обновления отношения после задержки и что это задержка? Или в какой момент отношения обновляются после удаления NSManagedObject?

Ответ 1

Да, вы правы. Ответ неправильный. Что касается второго момента. Метод -deleteOdject не удаляет объект, поскольку вы ожидали, что он просто пометит объект как удаленный. Чтобы выполнить удаление, вам нужно сохранить контекст управляемого объекта, а затем вы увидите, что правило nullify работает так, как ожидалось. Если вы не хотите сохранять контекст в этот момент, вы можете выполнить два пути:

  • Явно удалить связь:

    NSManagedObject* objectToDelete = [instanceOfA.relationToB lastObject];
    [context deleteObject:objectToDelete];
    NSMutableSet* relationships = [instanceOfA mutableSetValueForKey:@"relationToB"];
    [relationships removeObject:objectToDelete];
    
  • Попросите контекст обработать его будущие изменения (это означает рассчитать изменения, вызванные вашим удалением):

    [context processPendingChanges];
    

В вашем примере:

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

После этого вы увидите ожидаемый результат.

NSManagedObjectContext делает -processPendingChanges самостоятельно в конце цикла цикла или при выполнении -save:, поэтому вы видите некоторую задержку.

Надеюсь, что это поможет.

Ответ 2

После завершения изменений в объектах Core Data вы должны вызвать сохранить: в контексте управляемого объекта. Я предполагаю, что операция сохранения обновит все отношения.