Impossible de supprimer dans Core Data

colas_colas_ Membre
juin 2013 modifié dans Objective-C, Swift, C, C++ #1

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...


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...  :o


  • colas_colas_ Membre
    juin 2013 modifié #6

    @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



    Core Data: annotation: repairing missing delete propagation for to-many relationship <myRelatioship> on object

    Mais, je trouve ça bizarre... (qu'on ait besoin de faire un save pour supprimer un objet)


    Vous avez des explications ?


  • colas_colas_ Membre
    juin 2013 modifié #7

    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é)


  • FKDEVFKDEV Membre


    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 !

     




    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...
  • AliGatorAliGator Membre, Modérateur
    ça dépend aussi de la delete rule de ta relationship. Si c'est cascade, alors la suppression de A va aussi supprimer B, si c'est nullify alors la suppression de B va enlever la relation dans A, et la suppression de A va aller dans B supprimer les relations de B vers A...


    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. 


  • berfisberfis Membre
    juin 2013 modifié #12

    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.


     


    Note, however, that an object being marked for deletion from a context is not the same as its being marked for deletion from a persistent store. If an object is created and deleted within the same transaction"that is, without an intervening save operation"it will not appear in the array returned by NSManagedObjectContext's deletedObjects method or in the set of deleted objects in aNSManagedObjectContextDidSaveNotification notification.

     


    Huit ans d'existence, quelques centaines de milliers d'utilisateurs... un tel bug ne serait pas passé inaperçu, tout de même...


     

  • colas_colas_ Membre
    juin 2013 modifié #13

    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 ;)


  • berfisberfis Membre
    juin 2013 modifié #14

    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!


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