web-dev-qa-db-fra.com

Comment puis-je suivre/observer tous les changements dans un sous-graphe?

J'ai un NSManagedObjectContext dans lequel j'ai un certain nombre de sous-classes de NSManagedObjects telles que certaines sont des conteneurs pour d'autres. Ce que j'aimerais faire, c'est regarder un objet de niveau supérieur pour être averti de tout changement apporté à l'une de ses propriétés, associations ou propriétés/associations de l'un des objets qu'il contient.

L'utilisation du 'hasChanges' du contexte ne me donne pas assez de granularité. La méthode 'isUpdated' des objets ne s'applique qu'à l'objet donné (et à rien dans ses associations). Existe-t-il une solution commode (peut-être basée sur le KVO) où puis-je observer des changements dans un contexte limité à un sous-graphe?

57
David Carney

Vous voudrez écouter la variable NSManagedObjectContextObjectsDidChangeNotification pour enregistrer toutes les modifications apportées à votre modèle de données. Cela peut être fait en utilisant le code suivant:

[[NSNotificationCenter defaultCenter] 
      addObserver:self 
         selector:@selector(handleDataModelChange:) 
             name:NSManagedObjectContextObjectsDidChangeNotification 
           object:myManagedObjectContext];

qui déclenchera -handleDataModelChange: lors de toute modification du contexte myManagedObjectContext.

Votre méthode -handleModelDataChange: ressemblerait à ceci:

- (void)handleDataModelChange:(NSNotification *)note
{
    NSSet *updatedObjects = [[note userInfo] objectForKey:NSUpdatedObjectsKey];
    NSSet *deletedObjects = [[note userInfo] objectForKey:NSDeletedObjectsKey];
    NSSet *insertedObjects = [[note userInfo] objectForKey:NSInsertedObjectsKey];

    // Do something in response to this
}

Comme vous pouvez le constater, la notification contient des informations sur les objets gérés qui ont été mis à jour, supprimés et insérés. À partir de ces informations, vous devriez pouvoir réagir aux modifications apportées à votre modèle de données.

129
Brad Larson

voici un exemple simple dans Swift:

    NotificationCenter.default.addObserver(forName: .NSManagedObjectContextObjectsDidChange, object: nil, queue: nil) { note in
        if let updated = note.userInfo?[NSUpdatedObjectsKey] as? Set<NSManagedObject>, updated.count > 0 {
            print("updated: \(updated)")
        }

        if let deleted = note.userInfo?[NSDeletedObjectsKey] as? Set<NSManagedObject>, deleted.count > 0 {
            print("deleted: \(deleted)")
        }

        if let inserted = note.userInfo?[NSInsertedObjectsKey] as? Set<NSManagedObject>, inserted.count > 0 {
            print("inserted: \(inserted)")
        }
    }
19
Ilias Karim

pour moi, c'est juste perdu après deux func, peut-être cela économiser des heures pour quelqu'un

func controllerWillChangeContent(controller: NSFetchedResultsController) {
    tableView.beginUpdates()
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    tableView.endUpdates()
}
0
zmj110