Impossible de supprimer dans Core Data
Bonjour,
j'ai un NSManagedObject qui ne veut pas disparaà®tre !!
J'ai pourtant tout fait !
[myMOC deleteObject:myObject] ;
[myMOC processPendingChanges] ;
[myMOC save:NULL] ;
Mais, quand on lui demande s'il est isDeleted, il répond non.
En revanche, ses attributs et ses relationships sont passés à nil.
Avez-vous déjà vu des objets récalcitrants comme ça ?
Autre info, si je continue mon programme, je vais avoir l'erreur :
Illegal attempt to establish a relationship 'myRelationship' between objects in different contexts
alors qu'il me semble que je n'ai qu'un seul contexte (je travaille avec NSPersistentDocument)
Merci !
PS : la seule différence entre avant et après, c'est qu'après il est en mode "fault" alors qu'avant il ne l'est pas.
PPS : en plus, prepareForDeletion est appelée !!
PPPS : je pense que c'est une question de thread... mais en fait je n'en suis pas si sûr...
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Si tu as créé myObject pour ensuite faire un delete dessus sans aucun save entre les deux opérations, il est possible que isDeleted soit positionné à NO. En effet, isDeleted indique que l'objet sera supprimé du store lors du prochain save. Donc s'il n'a jamais été dans le store, isDeleted renverra NO.
Le deleteObject: supprime l'objet de ton graphe (d'où le fault). Le save supprime celui-ci de ton store.
Question bête, ton problème tu l'as sur device ? Perso, j'ai eu un problème de ce genre en testant sur le simulateur, et sur l'appareil tout fonctionnait correctement...
Non, c'est sur une appli osx.
Je me demande si ce n'est pas lié à la suppression dans les relations.
Mon objet fait référence à un autre, et dans la relation j'ai l'option nullify.
En tous cas, merci de vos réponses
Oups... Désolée, j'ai pas fait gaffe à la section...
@kubernan : tu avais raison !
En faisant un save, je n'ai plus de problème.
Je précise : un save après la création de l'objet ET un save après le delete !!
De plus, juste avant le second save (celui après le delete), CoreData me dit dans la log
Mais, je trouve ça bizarre... (qu'on ait besoin de faire un save pour supprimer un objet)
Vous avez des explications ?
Bon, je crois que j'ai trouvé !!
En fait, le problème vient des ordered relationships.
Cocoa implémente au runtime des méthodes qui sont buguées.
(cf. http://stackoverflow.com/questions/7385439/exception-thrown-in-nsorderedset-generated-accessors)
J'avais corrigé ce bug pour l'ajout d'éléments dans une relation, mais pas pour le remove !!!
Avec ceci, je n'ai plus besoin de faire un save pour que ça marche !
Il me reste une question, que les habitués de Core Data trouveront j'espère évidente
Si j'ai une entité A qui pointe vers une Entité B, avant de supprimer B, est-ce que je dois enlever B des relations de A ?
Je pensais que non, mais il semble que c'est oui !
PS : pour corriger le bug d'Apple automatiquement, il y a https://github.com/CFKevinRef/KCOrderedAccessorFix/blob/master/NSManagedObjectModel%2BKCOrderedAccessorFix.m (je n'ai pas encore testé)
Si la relation va dans les deux sens, non.
Autrement dit, si B a une relation vers A (ce qui est fortement conseillé, mais pas nécessaire), core data va retrouver A et retirer B de la relation.
Si ça ne marche pas, c'est peut-être causé par le bug lié aux ordered relationships...
Mais pour que tout ça marche bien tout seul il faut qu'il puisse retrouver les relations dans les 2 sens et pour cela il faut comme le mentionne FKDEV que toutes les relations aient une relation inverse de définie, c'est d'ailleurs LA raison pour laquelle Xcode te recommande fortement d'ajouter une relation inverse a chaque relationship.
Normalement, mes relations ont toute un inverse.
Je vous tiens au courant si je trouve.
merci
Ouais j'ai bien des inverses, tout est en nullify.
Je me dis que ça doit être un bug de core data.
Hello,
Tout est écrit là :
Deleting a Managed Object
This removes the managed object from the object graph. Just as a new object is not saved to the store until the context is saved, a deleted object is not removed from the store until the context is saved.
Huit ans d'existence, quelques centaines de milliers d'utilisateurs... un tel bug ne serait pas passé inaperçu, tout de même...
Perso je lirai les choses différemment :
<<
Deleting a Managed Object
This removes the managed object from the object graph.
>>
Pour moi, si l'objet n'est plus dans le graphe, il doit aussi disparaà®tre des relations. Ensuite que l'objet reste dans le store tant qu'il n'y a pas de save, oui ça me semble normal. Pour moi, le store = "le fichier où les données sont enregistrées" (avec quelques subtilités). Mon problème c'est pas que l'objet reste dans le store après le delete, c'est que les nullify ne marchent pas. Ensuite, c'est peut-être autre-chose, j'ai cru lire que si les relations en question étaient observées, ça pouvait gêner. Comme je me sers de mon modèle dans les views, avec les bindings d'interface builder.........
En tout cas, merci de te pencher sur mes soucis de Core Data
Lorsque l'objet n'est plus dans le graphe, il va de soi qu'il disparaà®t des relations... si elles sont correctement établies. C'est-à -dire, si elles sont bien dans les deux sens (un coup d'oeil dans l'éditeur pour le vérifier) et si elles sont du bon type, Nullify ou Cascade, ça dépend du sens de la relation et surtout de la façon dont les objets sont liés dans le modèle (par exemple, supprimer un département ne supprime pas les employés qui en font partie, mais supprimer une voiture supprimera aussi les pièces qui la composent). C'est cette définition de la relation qui n'est pas correcte si on en croit ton message d'erreur:
repairing missing delete propagation for to-many relationship
En général, tu ne devrais pas avoir à contrôler le boulot de Core Data. Si tu supprimes un objet, c'est comme si tu faisais un "removeSubview": l'objet ne doit plus être considéré comme valide, il peut retourner n'importe quelle valeur – en général il plante l'application.
Maintenant, s'il subsiste une référence sur cet objet (genre un binding "maison"), il se peut que le décompte ARC reste supérieur à zéro, et donc l'objet ne sera pas désalloué...
Bonne chasse!