Modèle, Vue et Undo

2»

Réponses

  • Entretemps, moi j'en suis là :


  • berfisberfis Membre
    mai 2015 modifié #33

    Bonjour,


     


    Je déterre mon propre sujet pour donner ma dernière solution, qui ne fait appel qu'à  une seule notification existante de Core Data. Je ne passe plus par le awakeFromSnapshotEvents (qui en fait me forçait à  vérifier que l'objet appartenait bien au contexte du document courant), mais par une unique méthode du contrôleur :



    // - (void) modelChanged: (NSNotification*)notification
    // {
    NSArray *inserted = [notification.userInfo valueForKey:NSInsertedObjectsKey];
    NSArray *deleted = [notification.userInfo valueForKey:NSDeletedObjectsKey];
    NSArray *updated = [notification.userInfo valueForKey:NSUpdatedObjectsKey];
    NSMutableArray *viewsToRemove = [NSMutableArray new];
    for (Container *container in inserted)
    [self installRepresentationForObject:container];

    for (Container *container in deleted)
    for (ContainerView *theView in self.layoutView.subviews)
    if ([theView.container isEqualTo:container]) [viewsToRemove addObject:theView]; // Can't modify array inside the loop!

    for (Container *container in updated)
    for (ContainerView *theView in self.layoutView.subviews)
    if ([theView.container isEqualTo:container]) [theView setFrame:[container.rect rectValue]];

    for (ContainerView *theView in viewsToRemove)
    [theView removeFromSuperview];

    [self.layoutView display];

    Bon, ça fait un peu "force brute", mais du coup j'obtiens un seul "undo" quand plusieurs objets visuels sont ajoutés/détruits/déplacés. Auparavant, les modifications s'annulaient une par une, même si l'utilisateur avait l'impression d'avoir effectué une seule opération (genre tout sélectionner et effacer). Cette solution fonctionne " et c'est un avantage non négligeable " sans avoir besoin de vérifier si le contexte est le bon. Il l'est forcément, puisque l'objet observé par le contrôleur est son propre contexte.


     


    @ Ali : J'espère ne pas avoir une fois de plus réinventé la roue...  ;)


     


    NOTES:


     


    1. Dans la solution ci-dessus, j'ai dû rajouter un isKindOfClass pour m'assurer que l'objet modifié/inséré/détruit est bien du bon type (si l'on a plusieurs entités différentes bien sûr)


     


    2. Petit souci: lorsque Core Data "ressuscite" un objet, il le fait sous forme de fault. Autrement dit, on ne peut plus compter sur ses attributs (nil ou zéro). ça c'est embêtant. Quelqu'un sait-il comment "unfaulter" un ManagedObject? Faut-il refetcher l'objet? (je crée du néologisme hybride et hideux à  tour de bras)


Connectez-vous ou Inscrivez-vous pour répondre.