Comment installer un NSMutableArray comme attribut d'une entité Core Data?

Bonjour tout le monde.





J'ai défini une entité appelée "Map". Elle possède trois attributs:



scale: NSNumber avec NSFormatter (obligatoire si vous voulez, après édition, un NSNumber au lieu d'une NSString, sinon > BANG <).

units: NSString

mapData: Binary Data? Transformed value?



Cet attribut mapdata pose un problème. J'ai une sous-classe de NSView qui stocke ses références de couleur dans une propriété NSMutableArray. C'est ce tableau que je veux mettre dans l'attribut mapdata. Mais ceci ne fonctionne pas:


<br />
[[[arrangedObjects mapController] lastObject] setValue: [colorReference matrice] forKey: @ &quot;mapData&quot;];<br />


"lastObject": c'est l'entité Map (unique).

[colorReference matrice] c'est le NSMutableArray de la NSView.



Maintenant, pour simplifier: Je veux que le NSMutableArray soit stocké dans l'attribut "mapData" de l'entité "Map", pour être stocké quand le doc est sauvé, et récupéré par la suite, puis transféré à  la NSView. Le design est clair, la façon de le réaliser beaucoup moins ...



Toute aide sera bienvenue!

Réponses

  • Déjà  je pense que stocker un NSArray (ou tout autre type de classe dite de collection) est une mauvaise idée car tu devra transformer ton objet en NSData. Imagine ensuite que tu veuille requeter avec un predicat etc ... Tu es coincé.



    Donc pourquoi ne pas créer une nouvelle table à  côté de de celle qui existe déjà  qui s'occuperai de stocker le contenu de ton array ? Tu peux ensuite définir la relation qu'il y a entre ces deux tables.
  • CéroceCéroce Membre, Modérateur
    juillet 2012 modifié #3
    Oui, crée une nouvelle entité Couleur, qui aura des attributs rouge, vert et bleu.

    Ensuite, tu pourras créer une relation one-to-many.



    Par contre, c'est un NSSet que tu vas récupérer, pas un NSArray, il faut voir si ça pose problème.
  • berfisberfis Membre
    juillet 2012 modifié #4
    Je stocke déjà  les couleurs elles-mêmes avec un attribut "transformable" et ça marche fort bien.



    Le NSMutableArray contient des entiers qui sont des références à  une couleur existante. Si j'ai trois couleurs, les valeurs contenues dans l'Array seront 0, 1 ou 2.



    Seulement... il y a 4096 points colorés. Ca fait une jolie array... Et si j'ai bien compris comment marche NSSet, ça va poser problème...
  • C'est très embêtant. Toute la structure de la NSView dépend de cette indexation. Il y aurait bien une solution, mais elle ferait appel à  un NSValueTransformer "maison": Je pourrais fabriquer une NSString à  partir du NSMutableArray (Core Data n'a rien contre les strings) et la transformation inverse serait:




    [color=#8e372e]<br />
    [color=#000000]    [/color][color=#66261e][b]NSMutableArray[/b][/color][color=#000000] *matrix = [[/color][color=#66261e][b]NSMutableArray[/b][/color][color=#000000] [/color][b][i]arrayWithArray[/i][/b][color=#000000]:[cdString [/color][b][i]componentsSeparatedByString[/i][/b][color=#000000]:[/color][color=#2d9748][b]@&quot;-&quot;[/b][/color][color=#000000]]];[/color][/color]<br />
    <br />
    


    Ou alors sous-classer un NSManagedObject qui ferait la conversion à  "awakeFromFetch" et "willSave", non?



    Non, décidément, Core Data, dès que tu quittes les clous tu te fais renverser. Idéal pour les recettes de cuisine...
  • CéroceCéroce Membre, Modérateur
    Ben, c'est une Base de données que tu as derrière. ça comporte pas mal d'avantages mais aussi des inconvénients.

    Soit dit en passant, Apple nous vends Core Data comme si c'était une techno magique et universelle, c'est bien évidemment faux.



    Avoir 4096 points et les stocker dans un NSMutableArray sous forme de NSNumbers, c'est bizarre et surtout inefficace. Stocker ça sous forme binaire semble bien plus approprié.
  • berfisberfis Membre
    juillet 2012 modifié #7
    Quand j'avais fait la même chose en Pascal il y a 20 ans, c'était des bytes et je faisais des BlockMove directement en mémoire... 4096 bytes sur un MacPlus, et c'était aussi rapide que maintenant image/cool.gif' class='bbc_emoticon' alt='8--)' />



    Ton commentaire sur Core Data me rassure, je pensais que j'allais avoir droit au couplet sur l'excellence du framework.



    A part ça, j'ai un truc qui marche (c'est vilain, lourd, mais ça marche pour le moment) j'utilise NSArchiver/Unarchiver pour stocker mon array sous forme NSData. A la récupération, ça redevient un mutable array et je peux le coller dans ma NSView.



    Bon, je sais quand récupérer mon NSData (c'est quand l'utilisateur passe la commande pour l'afficher). Ce que je ne sais pas, c'est quand la placer dans l'entité. Il n'y aurait pas un protocole du document genre "isAboutToSaveDocument"?



    PS tardif: Céroce, si j'ai choisi un NSMutableArray au lieu d'un vecteur C, c'est parce que je voulais en faire une propriété, et que seuls les objets peuvent en être. J'avais commencé par un int colorRef [63] [63]...



    Le rêve, mais je ne vois pas comment, serait d'établir une connexion entre cette propriété de la vue et l'attribut de l'entité Core Data... ja, ja, ja... image/huh.gif' class='bbc_emoticon' alt='???' />
  • berfisberfis Membre
    juillet 2012 modifié #8
    Bon, alors voilà .



    Core Data sérialise mon NSMutableArray de façon transparente si le type de l'attribut est "Transformable". Excellente nouvelle. Du coup ça devient simple:
    [matrix setColorReference:[[mapController content]valueForKey:@&quot;mapData&quot;]];
    


    où "matrix" est ma sous-classe de NSView, "colorReference" sa variable d'instance pointant sur le MutableArray, "mapController" l'entité qui stocke l'attribut transformable.



    Voilà  pour la lecture du fichier qui affiche la "carte" dans la vue. Pour l'édition, j'effectue l'inverse, mais dans le code de la NSView:


    [[mapController content] setValue:colorReference forKey:@&quot;mapData&quot;];
    




    Comme l'attribut "mapData" est conforme KVO, Core Data indique qu'il est modifié, et rend l'opération annulable.



    La solution n'est peut-être pas géniale, ni même la meilleure, mais elle ne fait pas appel à  du bricolage. J'ai résolu le problème des références (le ObjectController pour la NSView, et réciproquement), à  l'aide de propriétés IBOutlet dans mes sous-classes. Dans IB, j'établis les connexions, et après... je laisse les frameworks bosser pour moi. Il le font mieux que moi de toute manière...



    Merci pour vos judicieux conseils: même si je ne les applique pas forcément, ils me montrent des possibilités et me poussent à  aller plus loin.
Connectez-vous ou Inscrivez-vous pour répondre.