[Résolu] Delete rules pour une double relation Core Data
berfis
Membre
Bonsoir,
Je ma bagarre avec les delete rules des relations entre entités Core Data, soit je n'y comprends rien, soit j'ai un retain cycle quelque part...
Eleve <
>> Resultat <<
> Test <<
> Classe
L'affichage me donne ce que je veux, c'est quand je tente de détruire une entité que ça ne marche pas.
Elève --->> Resultat : Cascade
Eleve <--- Resultat : Nullify
Resultat <<--- Test : Cascade
Test <--- Resultat : Nullify
Donc:
Si je retire un élève, ses résultats sont supprimés, mais si je supprime un résultat l'élève reste.
Si je supprime un test, les résultats sont supprimés, mais si je supprime un résultat le test reste.
Si je supprime un élève ou un test, cela fonctionne comme prévu dans l'application Core Data Editor, mais pas dans la mienne: Si un test est supprimé, il reste dans la base, mais sa Classe est à NIL. Les résultats restent attribués à l'élève, et au test. En fait on se retrouve avec
Eleve <
>> Resultat <<
> Test Classe
Donc je penche pour un retain cycle, mais comment s'en assurer? Quel devrait être le type des attributs? J'ai dérivé les classes "Eleve", "Test" et "Resultat" mais comment déclarer leurs propriétés?
Un coup de main serait le bienvenu... D'avance merci.
Je ma bagarre avec les delete rules des relations entre entités Core Data, soit je n'y comprends rien, soit j'ai un retain cycle quelque part...
Eleve <
>> Resultat <<
> Test <<
> Classe
L'affichage me donne ce que je veux, c'est quand je tente de détruire une entité que ça ne marche pas.
Elève --->> Resultat : Cascade
Eleve <--- Resultat : Nullify
Resultat <<--- Test : Cascade
Test <--- Resultat : Nullify
Donc:
Si je retire un élève, ses résultats sont supprimés, mais si je supprime un résultat l'élève reste.
Si je supprime un test, les résultats sont supprimés, mais si je supprime un résultat le test reste.
Si je supprime un élève ou un test, cela fonctionne comme prévu dans l'application Core Data Editor, mais pas dans la mienne: Si un test est supprimé, il reste dans la base, mais sa Classe est à NIL. Les résultats restent attribués à l'élève, et au test. En fait on se retrouve avec
Eleve <
>> Resultat <<
> Test Classe
Donc je penche pour un retain cycle, mais comment s'en assurer? Quel devrait être le type des attributs? J'ai dérivé les classes "Eleve", "Test" et "Resultat" mais comment déclarer leurs propriétés?
Un coup de main serait le bienvenu... D'avance merci.
Mots clés:
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
T'as fait un clean ?
Cf ceci
Je ne les compte plus... et détruire le storedata idem...
Dans mes classes dérivées, je n'ai jamais deux retain qui se croisent pourtant. Par exemple, un test A des résultats (retain) et un résultat APPARTIENT A un test (assign)...
Une propriété assign a une delete rule Nullify, une propriété retain a une delete rule Cascade...
À tout hasard, avant de supprimer une entité vérifie si toutes les relations inverses sont bien renseignées (c'est-à -dire que Core Data a bien symétrisé les liens entre tes objets). Si ce n'est pas le cas, ça pourrait expliquer ton cas.
Salut colas2,
J'ai vérifié dans le Core Data Editor (pratique cette appli) et tout est bien relié. Dans le sens de la création, ça marche très bien, c'est la suppression qui pose problème.
Je regarde du côté de refreshObject:mergeChanges...
Est-ce que tu sauves tes données avant de faire ton delete ça change quelque chose ?
Cette appli a l'air effectivement super !
Je crois que j'ai mis la main dessus. C'est la partie Contrôleur de l'application qui était "fautive" (en fait, elle faisait parfaitement son travail, j'ai juste oublié de réfléchir jusqu'au bout...)
Pour pouvoir détruire un Test appartenant à une Classe, je suis obligé de les lister dans une NSTableView, avec des boutons + - pour agir sur la liste.
Comme je suis un aficionado du binding, j'ai donc associé un contrôleur à cette table et... lié son Content Set au set de la Classe courante (oui oui, les puristes, il existe un binding pour un set, même dans un array controller. Et ça fonctionne.)
Le souci, c'est qu'à ce moment-là , le contrôleur ne gère plus les Tests eux-mêmes, mais le set de la Classe auquel ils appartiennent. Et donc, en cliquant sur mon bouton -, je ne supprime pas le Test, je le retire du set qui le contient.
Je me retrouve donc avec un Test qui flotte à la dérive dans le document, qui n'appartiendra plus à une Classe et donc ne sera plus listé dans la table...
Après cette illumination très matinale " j'avais dû continuer à y réfléchir en dormant " restait à trouver une solution (nan, pas de datasource, merci). J'en ai vu deux:
1) le bouton remove passe par le appDelegate (beurk)
2) dériver l'arrayController et modifier sa méthode remove.
J'ai fini par créer une classe ContentSetController qui implémente remove ainsi:
Et du coup ça marche, bien sûr... Merci Core Data Editor, sans lui je ne me serais aperçu de rien, puisque le graphe restait cohérent.
La solution avait déjà été donnée par Kubernan dans le lien indiqué par Larme, mais le problème, lui, était différent: