[Résolu] - NSArrayController, Sort Descriptors et bindings
skimpy
Membre
Bonjour,
J'ai un problème de tri dans une NSTableView. Celle-ci est lié à un NSArrayController qui est paramètré entre autre avec l'option Auto Rearrange Content (le contenu est bindé sur un Managed Object Context). J'ai bindé le Sort Descriptors du NSArrayController à une méthode sortDescriptors comme indiqué dans la doc Apple. J'ai donc dans mon File's Owner, la méthode suivante :
- (NSArray *)sortDescriptors
{
return [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@name ascending:YES]];
}
et dans mon awakeFromNib, ceci pour la NSTableView :
[ibGroupsTableView setSortDescriptors:[self sortDescriptors]];
Lorsque j'ajoute des données, celles-ci ne sont pas triées. Par contre, si je quitte l'application et que je la relance, c'est bon.
Auriez-vous une idée ?
Merci.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Bonjour,
Il faut passer la message -rearrangeObjects au contrôleur en fin d'édition des données.
Bonjour berfis,
Je vais tester mais c'est assez déroutant car dans le lien suivant (https://developer.apple.com/library/mac/#technotes/tn2203/_index.html#//apple_ref/doc/uid/DTS40011838) il est stipulé qu'à partir de 10.5, il n'est plus nécessaire d'appeler cette méthode :
Est-ce que ça pourrait venir du fait que j'utilise un MOC temporaire pour faire l'insertion des objets ? Le MOC principal étant enregistré auprès du centre de notification pour recevoir la notification NSManagedObjectContextDidSaveNotification.
Merci.
Oui... je sais... de sorte qu'entre les sort descriptors ajoutés par code, ceux définis dans IB, les cases "Auto" cochées, on finit par s'y perdre et manifestement cocoa aussi.
Décoche l'auto, enlève le sort descriptor de IB, et ajoute setSortDescriptor et rearrangeObjects par code. C'est peut-être dommage mais ça a le bon goût de fonctionner.
De plus, si la TableView est liée au contrôleur, c'est lui qui va faire le travail. Inutile d'ajouter un sort descriptor à la TableView.
Es tu certain que ton NSArrayController est au courant des nouveaux objets ?
A priori oui puisque tu utilises Core Data mais même avec Core Data il me semble qu'il faut toujours passer par des méthodes keyValueCodingProtocol comme insertObject:(id) inMyObjectsAtIndex:(NSUInteger)index;.
En général quand les bindings ne "marchent pas" c'est souvent qu'ils n'ont pas été "déclenchés".
rearrangeObjects lui fait prendre en compte les nouveaux objets.
Comme le dit laudema, les bindings n'ont pas été "déclenchés", cela signifie que l'ajout de nouveaux enregistrements à la table ne sont pas KVO. Le KVO/KVC est une magie... un peu noire qui nécessite à elle seule un chapitre de documentation:
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/KeyValueCoding.html
Un ArrayController "branché" sur un ManagedObjectContext est probablement modifié pour prendre en compte le KVO avec Core Data (ainsi que mettre à jour le "Undo/Redo"). Mais tous les bindings "maison" lui passent un peu au-dessus de la tête et c'est en cela que -rearrangeObjects corrige le tir.
J'ai supprimé tout ce qui était bindé via IB et je l'ai mis dans mon awakeFromNib
Ca n'a pas résolu le problème. J'ai aussi rajouté ça pour voir si le KVO fonctionnait :
Je pense que c'est OK car quand je fais un save sur mon MOC "secondaire", il envoie la notification NSManagedObjectContextDidSaveNotification qui est reçu par mon MOC principal et juste après je reçois la notification arrangedObjects. Dans la méthode observeValueForKeyPath..., j'ai choisi d'afficher le keyPath et l'objet et voilà la log qui s'affiche :
Pour info, le problème vient de l'option "Uses Lazy Fetching" du NSArrayController ... Sans cette option activée, le tri fonctionne parfaitement.
L'autre problème maintenant, c'est que j'ai besoin du Lazy Fetching ...
Je ne sais pas si le contrôleur peut effectuer un tri sur des faults... ça me paraà®t du même genre que trier des chaussettes que tu n'as pas encore achetées...
Finalement c'était bien un problème de liaison non rafraichie par défaut de "trigger action".
A première vue c'est un problème connu : si on cherche NSArrayController uses lazy fetching NSSortDescriptor sur Google on lit des choses comme
La solution pour waschhauss media indiquée ici est de faire
à la fin de l'opération.
Merci laudema et berfis pour votre aide. C'est tout bon maintenant !
Edit : finalement, au démarrage de l'appli quand le Uses Lazy Fetching est activé avec le sortDescriptors, il charge tout ... J'ai fait le test :
- ULF activé et sortDescriptors désactivé : 34 MB utilisation mémoire
- ULF activé et sortDescriptors activé : 92 MB