Étrange phénomène parent / enfant NSManagedObjectContext

J'ai créé deux contexts comme celui-ci:

// create writer MOC _privateWriterContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [_privateWriterContext setPersistentStoreCoordinator:_persistentStoreCoordinator]; // create main thread MOC _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; _managedObjectContext.parentContext = _privateWriterContext; 

J'ai un NSFetchResultedController initié avec _managedObjectContext .

Je sais que c'est étrange, mais _privateWriterContext un logging au parent à _privateWriterContext , je le saving .

Ce qui est surprenant est ce context enfant et donc FRC est averti de cet événement. Pourquoi? Je n'ai pas reset enfant, ou quoi que ce soit d'autre. Je pensais qu'ils sont des entités indépendantes tant que le context de l'enfant ne sera pas sauvé.


Dans l'article @pteofil j'ai trouvé cette ligne:

Quand un changement est fait dans un context, mais pas enregistré, il est visible à tous ses 'descendants, mais pas à ses' ancêtres.

.. il est poussé vers le magasin persistant (via le coordinateur de magasin persistant) et devient visible pour tous les contexts connectés au magasin.

Ceci n'est pas censé se produire. L'ajout d'un object NSManagedObject ('record') au parentContext ne rendra pas l'enfant conscient de cet object automatiquement. Ce n'est que lorsque vous faites que childContext exécute une extraction, qu'elle récupère à partir de parentContext. Pour comprendre ce qui se passe dans votre cas, voici quelques suggestions:

  • déterminez quand une extraction est exécutée sur childContext (ceci est effectué par le fetchedRestultsController lorsque vous l'avez configuré Vérifiez si cette extraction se produit avant ou après l'ajout de managedObject au parentContext).
  • Définissez des points d'arrêt dans les quatre callbacks des delegates de la command fetchedResultsController pour savoir pour quel object les methods sont appelées (et voyez si c'est l'object que vous venez d'append au parentContext).
  • Assurez-vous absolument de savoir dans quel context vous envoyez des messages.

J'ai utilisé une approche similaire, mais différente: childContext est le context est utilisé pour parsingr de nouveldatatables (sur une queue privée), et quand cette parsing est terminée, les appels chid save :. Cela sauvegardera les changements jusqu'au parent, qui est dans mon cas le mainQueueContext. Cet appel à save: entraînera la réception par mainQueueContext de tous les objects nouvellement analysés, et tout fetchedResultsController utilisant ce mainQueueContext appellera alors ses methods déléguées pour les nouveaux objects / changed / updated / delete. Vous pouvez également essayer d'inverser votre relation enfant / parent et voir si cela fonctionne comme décrit dans les documents, juste pour savoir ce qui se passe.

Je recommand fortement d'éviter les configurations de context parent-enfant. Notre livre va dans le détail pourquoi ils conduisent souvent à un comportement étrange: https://www.objc.io/books/core-data/

Petite histoire: Ils ne sont pas aussi indépendants que vous pourriez le penser.

Utilisez plusieurs contexts partageant un même coordinateur de magasin persistant si vous avez besoin de plusieurs contexts.