KVO et CoreData : cas où le setter d'un attribut CoreData est implémenté

2»

Réponses

  • AliGatorAliGator Membre, Modérateur

    Imagine que mes attributs sont : 
     
    isRed
    isBlue
    isOpaque
    isBW
     
    et tu ne peux pas être simultanément isRed, isBlue et isBW

    Bah là  c'est ton modèle qui est mal fichu, si tu as des attributs exclusifs et que tu utilises autant de champs que de valeurs pour les stocker.

    Pour ça rien de plus simple : comme le dit Berfis c'est des options mutuellement exclusives. Donc tu fais un enum pour ça, c'est fait pour.
    typedef NSENUM(int, ColorMode) { ColorModeRed, ColorModeBlue, ColorModeMonochrome };
    Du coup :
    - dans ta base CoreData ou dans ton Modèle Objet tu as un attribut de type ColorMode (au niveau du stockage dans CoreData en interne ça sera un int, mais ça sera transparent car dans ta sous-classe de NSManagedObject tu mettras ColorMode et non int pour le type de l'attribut donc la conversion sera implicite). C'est la donnée primitive
    - Et si tu veux quand même les méthodes isRed, isBlue, isBW (voire les méthodes setRed: setBlue: et setBW:) bah tu peux les implémenter, ça sera juste des méthodes utilitaires / wrapper, un peu comme si tu codais une méthode fullname sur une classe personne " alors que tu as déjà  l'attribut firstname et lastname dans CoreData " juste pour avoir une API plus sympa, mais c'est pas pour autant que tu vas stocker fullname en plus de stocker firstname et lastname, c'est juste une donnée transciente / une méthode utilitaire / de commodité.

    C'est toute la différence entre le modèle et l'API. C'est le principe même de l'encapsulation, donc la séparation entre une API (pensée pour être facile à  manipuler) et l'implémentation et la structure interne d'un objet / d'une classe (qui peut être + complexe que l'API semble le laisser penser mais ça on s'en fout l'utilisateur de la classe n'a pas besoin de connaà®tre l'intérieur du moteur pour conduire la voiture)
  • Merci pour vos conseils. 


    J'ai transformé mon modèle et mes méthodes en conséquence.


     



     


     


    (au niveau du stockage dans CoreData en interne ça sera un int, mais ça sera transparent car dans ta sous-classe de NSManagedObject tu mettras ColorMode et non int pour le type de l'attribut donc la conversion sera implicite).

     


     


    Es-tu sûr de cela ?


    Les properties CoreData sont des NSNumber : je ne peux pas overwritter la property color.


  • AliGatorAliGator Membre, Modérateur
    Bien sur que j'en suis sur je l'ai pratiqué sur de nombreux projets.


    Quand tu demandes à  Xcode de générer ta sous-classe de NSManagedObject qui correspond à  ton entité, tu as une case à  cocher pour dire si tu veux utiliser les types primitifs ou pas pour les valeurs numériques. Si oui ça utilise des int/float/double/... sinon ça utilise des NSNumbers.


    L'implémentation à  la volée de ces propriétés (Grâce à  @dynamic et au framework CoreData qui génère l'implémentation de ces propriétés au Runtime) prend en compte si c'est un type primitif ou pas, et encapsule ou non dans un NSNumber (c'est ce que l'on appelle de m'autoboxing, c'est aussi utilisé par KVC) automatiquement.


    Une fois que Xcode a généré le fichier de ta sous-classe de NSManagedObject et qu'il a déclaré toutes les @property, tu peux dans souci remplacer le type d'une propriété int par un autre type qui a un stockage équivalent (genre un NS_ENUM(int XXXX)), il fera un implicit cast dans souci puisqu'une fois compilé les deux sont équivalents.
  • berfisberfis Membre
    janvier 2014 modifié #35

    Bonsoir, ça tombe bien, je viens de générer une sous-classe et je convertis sans arrêt de NSNumber à  BOOL, etc. J'ai loupé la case à  cocher, manifestement.


     


    Après coup, je suppose qu'on peut changer:


     


    @property (nonatomic, retain) NSNumber *isMarked; // généré par Xcode

     

    en:

     


    @property (nonatomic) BOOL isMarked;

     

    sans danger ?

     

  • AliGatorAliGator Membre, Modérateur
    A priori je pense que oui. Les accesseurs générés par @dynamic s'adapteront en conséquence normalement.
  • En fait j'utilise mogenerator, qui génère des NSNumber.


     


    Merci pour ces précisions !


  • AliGatorAliGator Membre, Modérateur
    Et y'a pas un flag dans les options de mogenerator genre --useatomictypes ou je sais pas quoi ?!
  • berfisberfis Membre
    janvier 2014 modifié #39

    La réponse est là  pour MOGenerator:


    http://stackoverflow.com/questions/5021140/how-do-i-get-mogenerator-to-recognize-the-proper-type-for-transformable-attribut


    A propos, j'ai fini par voir où il était dans Xcode: à  la dernière étape de la création de la sous-classe...  :)


  • @berfis


    Es-tu sûr que la page SO à  laquelle tu fais référence concerne les properties de type primitif ?


     


    @Ali


    Rien trouvé de ce genre


     


    Je vais rester sur ma pratique habituelle de mogenerator : ajouter Value à  l'attribut pour avoir sa valeur primitive.


  • AliGatorAliGator Membre, Modérateur
    Le terme exact est "scalar types" et pas "atomic types" comme je l'avais marqué plus haut, peut-être que ça peut changer la donne dans tes recherches ?
Connectez-vous ou Inscrivez-vous pour répondre.