IPB

Bienvenue invité ( Connexion | Inscription )

 
Reply to this topicStart new topic
> Sauvegarde d'une appli multi documents, NSArray et NSDictionary...
Options
rodo
posté 9 Oct 2005, 19:01
Message #1


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 031
Inscrit : 9 Nov 2003
Lieu : Région de Paris
Membre no 11 457



Salut je m'arrache les cheveux en ce moment pour arriver à sauvegarder mes document. Mon appli est très simple:

Dans "MyDocument", je stocks dans un NSMutableDictionary les variables d'un NSTableView.

Le dataSource de ce NSTableView est dans une autre classe "Fiche" contenant un NSMutableArray stockant les dictionary de MyDocument.

L'appli fonctionne bien, sauf que je n'arrive pas à mémoriser les données dans un fichier sur le disque.

Il me faut donc sauvegarder le tableau de dictionnaire présent dans Fiche...

Pouvez vous me donnez un coup de pousse sur la façon de procéder ? Ca fait des heures que je nage dans les Archiver, Coder, dataRepresentation et autre NSData... j'ai un peu tout bidouillé sans succès...


Ce que j'ai fait :

Dans MyDocument :
CODE


- (NSData *)dataRepresentationOfType:(NSString *)aType
{
   [tableView deselectAll:nil];
   // Créer un objet NSData à partir du tableau
   return [[tableView dataSource] returnArchivedData];
}

- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
{
//envoie les données vers la focntion de désarchivage de Fiche
[[tableView dataSource] loadDataFromDisk: data];
[tableView reloadData];
   return YES;
}


Dans Fiche :
CODE

- (NSData *)returnArchivedData
{
return [NSArchiver archivedDataWithRootObject:fiche];
}


- (void)loadDataFromDisk: (NSData *)dataFromDisk;
{
// Libérer l’ancien tableau
   [fiche release];
// Lire le tableau à l’aide de l’objet de données
   fiche = [[NSUnarchiver unarchiveObjectWithData: dataFromDisk] retain];

}


A priori il faut utiliser NSCoder quelque part mais je suis perdu.

Merci de votre aide

Rodo sad.gif

Ce message a été modifié par rodo - 9 Oct 2005, 19:04.


--------------------
Go to the top of the page
 
+Quote Post
Doom Hammer
posté 9 Oct 2005, 21:35
Message #2


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 844
Inscrit : 10 Jul 2002
Membre no 2 871



Il faut implémenter le protocole NSCoding dans la class de l'object fiche.
Go to the top of the page
 
+Quote Post
rodo
posté 10 Oct 2005, 09:00
Message #3


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 031
Inscrit : 9 Nov 2003
Lieu : Région de Paris
Membre no 11 457



QUOTE(Doom Hammer @ 9 Oct 2005, 22:35)
Il faut implémenter le protocole NSCoding dans la class de l'object fiche.
[right][snapback]1359458[/snapback][/right]



Bonjour et merci de ta réponse

C'est bien ce que j'ai fait j'envoie ce soir ce que j'ai codé (la je suis au boulot)... mais en tout cas ça ne marche pas... le reste du code ça vous semble bien??


Pour cette ligne : [[tableView dataSource] loadDataFromDisk: data];
il me met un avertissement comme quoi loadDataFromDisk risque de ne pas répondre. Alors j'ai remplacé [tableView dataSource] par une variable de type Fiche (Fiche *toto) mais alors ça plante....

rodo

Ce message a été modifié par rodo - 10 Oct 2005, 09:03.


--------------------
Go to the top of the page
 
+Quote Post
f_cam
posté 10 Oct 2005, 11:17
Message #4


Moderating Daemon
*****

Groupe : Modérateurs
Messages : 6 345
Inscrit : 22 Feb 2004
Lieu : Yvelines/Cambridge (GB), dans mon pantalon
Membre no 15 207



Ou as tu implémenté ta méthode loadDataFromDisk? Si c'est dans Fiche, c'est bien une instance de Fiche qui doit etre la cible de cet appel, mais il faut bien sur créer une instance de fiche auparavant.

Montre ton code et on verra bien.
Le warning sur [[tableView dataSource] loadDataFromDisk] peut etre parce que le compilo ne connait pas le type de ta datasource, donc
CODE

[((LeTypeDeMaDataSource)[tableView dataSource]) loadDataFromDisk])


--------------------
G5 Bi 2GHz rev A, ATI X800 XT
Alu 17" rev A
MacBook core duo 1.83 GHz
Go to the top of the page
 
+Quote Post
rodo
posté 10 Oct 2005, 11:39
Message #5


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 031
Inscrit : 9 Nov 2003
Lieu : Région de Paris
Membre no 11 457



LoadDataFromDisk est bien dans Fiche (voir mon premier post)... ce que je ne comprend pas c'est que [tableView dataSource] marche dans d'autres méthodes de MyDocument...


Merci je vois ça ce soir

à plus smile.gif

Ce message a été modifié par rodo - 10 Oct 2005, 11:42.


--------------------
Go to the top of the page
 
+Quote Post
Doom Hammer
posté 10 Oct 2005, 11:52
Message #6


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 844
Inscrit : 10 Jul 2002
Membre no 2 871



QUOTE(rodo @ 10 Oct 2005, 10:00)
Pour cette ligne : [[tableView dataSource] loadDataFromDisk: data];
il me met un avertissement comme quoi loadDataFromDisk risque de ne pas répondre. Alors j'ai remplacé [tableView dataSource] par une variable de type Fiche (Fiche *toto) mais alors ça plante....

lol T'as pas terminé ton programme si tu adoptes la programmation au pif.
Go to the top of the page
 
+Quote Post
rodo
posté 10 Oct 2005, 12:03
Message #7


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 031
Inscrit : 9 Nov 2003
Lieu : Région de Paris
Membre no 11 457



QUOTE(Doom Hammer @ 10 Oct 2005, 12:52)
QUOTE(rodo @ 10 Oct 2005, 10:00)
Pour cette ligne : [[tableView dataSource] loadDataFromDisk: data];
il me met un avertissement comme quoi loadDataFromDisk risque de ne pas répondre. Alors j'ai remplacé [tableView dataSource] par une variable de type Fiche (Fiche *toto) mais alors ça plante....

lol T'as pas terminé ton programme si tu adoptes la programmation au pif.
[right][snapback]1360131[/snapback][/right]



biggrin.gif au pif c'est un grand mot mais c'était surtout un essai pour essayer de comprendre ce qu'il ce passe. Pour moi les deux peuvent marcher... si non je veux comprendre pourquoi. Mais j'étudie sous toutes ces formes les façons d'enregistrer un document...


--------------------
Go to the top of the page
 
+Quote Post
rodo
posté 10 Oct 2005, 21:23
Message #8


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 031
Inscrit : 9 Nov 2003
Lieu : Région de Paris
Membre no 11 457



Bon voilà ce que j'ai fait dans Fiche... je pense que c'est bon ?

CODE

// Encodage
- (void)encodeWithCoder: (NSCoder *)coder
{
[coder encodeObject: fiche];
}

//décodage
- (void) setFiche: (NSMutableArray *)newFiche
{
   if (fiche != newFiche)
   {
[newFiche retain];
       [fiche release];
fiche = newFiche;
 
   }
}


- (id) initWithCoder: (NSCoder *)coder
{
   if (self = [super init])
   {
       [self setFiche: [coder decodeObject]];  
   }
   return self;
}



Bon j'y est encore passé la soirée et rien de nouveau sad.gif sad.gif

Voici MyDocument :
CODE


#import "MyDocument.h"
#import "Fiche.h"

@implementation MyDocument

- (id)init
{
   self = [super init];
   if (self) {

   }
   return self;
}

//valeur d'initialisation des varaibles
- (NSString *)returnDefaultValue
{
NSString *toto = @"vide";
return toto;
}

//Ajoute un ligne dans mon tableau. Est initialisé avec des valeurs par défauts !! : répond au bouton "ajouter"
- (IBAction)addData:(id)sender
{
NSMutableDictionary *newElement = nil;
newElement = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
  [self returnDefaultValue],  @"Nom",
  [self returnDefaultValue],  @"Type",
  [self returnDefaultValue],  @"Contenu",
  nil];

// Add
   [[tableView dataSource] addRow: newElement];
   
   // recharger le tableView
   [tableView reloadData];
}


//Efface une ligne et son contenu dans mon tableau : répond au bouton "effacer"
- (IBAction)deleteData:(id)sender
{
int     row = [tableView selectedRow];      // on récupère la ligne sélectionnée
   
   // On efface cette ligne :
   // on supprime dans le datasource les données de la ligne
   [[tableView dataSource] removeRow: row];
   
   // on recharge le table view avec les nouvelles données
   [tableView reloadData];
}

- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
   [super windowControllerDidLoadNib:aController];
   // Add any code here that needs to be executed once the windowController has loaded the document's window.
[tableView reloadData];
}

- (NSData *)dataRepresentationOfType:(NSString *)aType
{
   [tableView deselectAll:nil];
 ??????

}

- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
{
??????????
           Je ne vois pas comment charger mon dataSource (Fiche)

   return YES;
}


@end


Ce message a été modifié par rodo - 10 Oct 2005, 21:49.


--------------------
Go to the top of the page
 
+Quote Post
rodo
posté 10 Oct 2005, 22:30
Message #9


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 031
Inscrit : 9 Nov 2003
Lieu : Région de Paris
Membre no 11 457



Salut encore moi je sais que je poste un peu en vrac mais je fatigue... rolleyes.gif
Cette idée est-elle valable ? J'ai du mal à visualiser comment sauvegarder mon dataSource...

CODE


- (NSData *)dataRepresentationOfType:(NSString *)aType
{

   [tableView deselectAll:nil];
 
 return [NSArchiver archivedDataWithRootObject:[tableView dataSource]];
}

- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
{
 
[tableView setDataSource: [NSUnarchiver unarchiveObjectWithData:data]];
   return YES;
}


--------------------
Go to the top of the page
 
+Quote Post
julious
posté 10 Oct 2005, 23:28
Message #10


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 3 357
Inscrit : 16 Aug 2001
Lieu : dernier de la classe
Membre no 638



Je ne comprends vraiment pas pourquoi tu gères une TableView dans la classe MyDocument avec le dataSource qui est un objet à part et qui est donc une instance de Fiche si je comprends bien ? Est-ce que la classe de l'objet pointé par [tableView dataSource] implément le protocole <NSCoding> ? Ne peux tu pas avoir un pointeur sur l'instance de Fiche plutôt que de faire [tableView dataSource] à chaque fois ? Ou mieux, ne peux tu pas recentraliser la gestion des objets affichés dans la TableView et les faire gérer par la classe MyDocument ?


--------------------
Make something idiot proof and the world will make a better idiot.
Go to the top of the page
 
+Quote Post
rodo
posté 11 Oct 2005, 08:49
Message #11


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 031
Inscrit : 9 Nov 2003
Lieu : Région de Paris
Membre no 11 457



QUOTE(julious @ 11 Oct 2005, 00:28)
Je ne comprends vraiment pas pourquoi tu gères une TableView dans la classe MyDocument avec le dataSource qui est un objet à part et qui est donc une instance de Fiche si je comprends bien ? Est-ce que la classe de l'objet pointé par [tableView dataSource] implément le protocole <NSCoding> ? Ne peux tu pas avoir un pointeur sur l'instance de Fiche plutôt que de faire [tableView dataSource] à chaque fois ? Ou mieux, ne peux tu pas recentraliser la gestion des objets affichés dans la TableView et les faire gérer par la classe MyDocument ?
[right][snapback]1361002[/snapback][/right]


Salut et merci

Oui le dataSource est bien une instance de Fiche qui implémente bien le NSCoding. J'ai choisi de procéder de la sorte en vu de ce que je ferrais plus tard (Mon but est de pouvoir créer plusieurs instances de Fiche de façon à changer la dataSource de la tableView). Si ce n'est pas judicieux merci de ton avis je vais reconsidérer ma façon de faire... je vais déjà tester de créer un pointeur sur l'instance de Fiche au moins pour comprendre le fonctionnement de NSArchive et NSCoding.

Merci encore


--------------------
Go to the top of the page
 
+Quote Post
Doom Hammer
posté 11 Oct 2005, 09:01
Message #12


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 844
Inscrit : 10 Jul 2002
Membre no 2 871



Attention à l'appel de la super class :
QUOTE
- (id) initWithCoder: (NSCoder *)coder
{
   if (self = [super initWithCoder])
   {
       [self setFiche: [coder decodeObject]]; 
   }
   return self;
}


PS : connerie, c'est bien [super init] qu'il faut mettre

Ce message a été modifié par Doom Hammer - 16 Oct 2005, 18:17.
Go to the top of the page
 
+Quote Post
rodo
posté 11 Oct 2005, 11:24
Message #13


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 031
Inscrit : 9 Nov 2003
Lieu : Région de Paris
Membre no 11 457



merci je corrige ce soir....

Merci pour votre aide, je sais que j'en demande un peu beaucoup dans ce poste mais je suis vraiment bloqué... et en tant que novice, je ne suis pas toujours sûr de faire les choses de la façon la plus logique ! cool.gif


--------------------
Go to the top of the page
 
+Quote Post
rodo
posté 16 Oct 2005, 17:35
Message #14


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 031
Inscrit : 9 Nov 2003
Lieu : Région de Paris
Membre no 11 457



Salut

Voilà j'ai eu un moment pour retravailler la dessu. J'ai passé les méthodes de la source de donnée dans MyDocument tout en laissant pour un besoin plus tard le stockage de mes NSDocument dans "Fiche". Sinon j'ai laissé ça :

- (id) initWithCoder: (NSCoder *)coder
{
if (self = [super init])
{
[self setFiche: [coder decodeObject]];
}
return self;
}

Si je met [Fiche initWithCoder]:

j'ai cette erreur à l'ouverture de mon fichier archivé :

selector not recognized [self = 0x34d270]

Il semble que mon NSObject n'ai pas de méthode initWithCoder. Quelqu'un peu m'expliqué comment cela fonctionne plus en détail ?

En tout cas merci à tous pour votre aide ça m'a beaucoup aidé...

Au prochain problème !
biggrin.gif


--------------------
Go to the top of the page
 
+Quote Post
Doom Hammer
posté 16 Oct 2005, 18:16
Message #15


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 844
Inscrit : 10 Jul 2002
Membre no 2 871



Tiens oui j'avais dit une connerie, il faut bien appeller la méthode init de la super class et non pas initWithCoder, logique en fait.

Pour le selector not recognized c'est normal, tu appelles une méthod de class alors que tu as une méthode d'instance.
fiche doit être une instance de la class Fiche :
[fiche initWithCoder];

Mais es-tu sur de vouloir appeller initWithCoder directement ? D'habitude on l'appelle par l'intermediaire d'une instande de NSUnarchiver...

Ce message a été modifié par Doom Hammer - 16 Oct 2005, 18:19.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 utilisateur(s) sur ce sujet (1 invité(s) et 0 utilisateur(s) anonyme(s))
0 membre(s) :

 



Nous sommes le : 28th April 2024 - 15:24