Désarchiver/Archiver l'appDelegate

FloFlo Membre
07:49 modifié dans API AppKit #1
Bonjour à  tous,

Tout est à  peu près dans le titre, je n'arrive pas à  faire en sorte que mon AppDelegate soit initialisé à  partir d'une archive.

Comment dois-je faire ? Je voudrais que mon application teste si le fichier de données est présent, si oui initialiser l'AppDelegate à  partir d'un fichier, sinon faire son initialisation classique.

L'appDelegate implémente :
<br /> - (id) initWithCoder: (NSCoder *)aCoder;<br />- (void) encodeWithCoder: (NSCoder *)aCoder;<br />


Est-ce correct de faire ainsi ? :
<br /> - (id) init<br />{<br />    if ( &quot;fichier existe&quot;)<br />    {<br />       &quot;récupérer l&#39;archive et faire un self = [NSKeyedUnarchiver unarchiveObjectWithFile: appDataFile];<br />    }<br />    else<br />        self =  [super init];<br />}<br />


ça parait un peu cochon... non ?

Réponses

  • schlumschlum Membre
    07:49 modifié #2
    Beurk...

    C'est au dessus qu'il faut le gérer...
    Et en plus d'une faut pas oublier le "retain" après "unarchiveObjectWithFile" (objet auto-released) ; de deux, faut pas oublier le @try @catch (si le fichier est mal formé, ça balance une exception).
  • FloFlo Membre
    07:49 modifié #3

    C'est au dessus qu'il faut le gérer...


    Ben ouais c'est bien ce que je pensais, le truc c'est que l'AppDelegate est instancié dans un nib alors comment faire ?
  • schlumschlum Membre
    07:49 modifié #4
    Ben déjà  c'est pas avec "init" que t'arriveras à  faire quelque chose...
    Les objets dans les .nib sont instanciés avec "initWithCoder", et c'est déjà  un archivage.
    Donc il faut le modifier via le awakeFromNib...
  • FloFlo Membre
    07:49 modifié #5

    il faut le modifier via le awakeFromNib...


    Sa veut dire qu'à  un moment dans awakeFromNib j'ai un truc comme ça ? :

    <br />- (void) awakeFromNib<br />{<br />&nbsp; &nbsp; // test présence fichier + try{}catch{}<br /><br />&nbsp; &nbsp; self = [NSKeyedUnarchiver unarchiveObjectWithFile: appDataFile];<br /><br />&nbsp; &nbsp; // en oubliant pas de faire un retain :-)<br />}<br />
    


    C'est pas un peu barbare sachant qu'il y a déjà  un self = [super init]; (par initWithCoder:) qui a été fait ?
  • schlumschlum Membre
    07:49 modifié #6
    Ah non, surtout pas comme ça...
    Variable par variable avec les accesseurs...
  • FloFlo Membre
    07:49 modifié #7
    heu... comme ça alors ? :

    <br /><br />- (void awakeFromNib<br />{<br /><br />// test présence fichier + try{}catch{}<br /><br />NSData *data = [NSData dataWithContentsOfFile: appDataFile];;<br />NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];<br /><br />self.var1 = [unarchiver decodeObjectForKey: @&quot;var1&quot;];<br />self.var2 = [unarchiver decodeObjectForKey: @&quot;var2&quot;];<br /><br />.....<br /><br />[unarchiver finishDecoding];<br />[unarchiver release];<br />}<br /><br />
    


  • schlumschlum Membre
    07:49 modifié #8
    Euh... Oui, sauf que du coup les try/catch sont mal placés, ils devraient être au niveau du "initForReadingWithData"

    This method raises an NSInvalidArchiveOperationException if data is not a valid archive.
    
  • FloFlo Membre
    07:49 modifié #9

    Euh... Oui, sauf que du coup les try/catch sont mal placés, ils devraient être au niveau du "initForReadingWithData"


    Oui bien sur, j'ai oublié de bouger la ligne de commentaire  ;D

    Merci !
    Une dernière petite question, si je fais ça plutôt dans un thread et dans la méthode applicationDidFinishLaunching: ça change pas grand chose non ?
  • CéroceCéroce Membre, Modérateur
    07:49 modifié #10
    Rien à  redire sur la technique, mais c'est quand même très étrange comme démarche, de vouloir archiver l'appDelegate.

    En général, soit notre appli est basée sur un document, soit on stocke quelques données dans les préférences. Dans les deux cas, on va maintenir des objets de la couche modèle, et on fera leur désarchivage dans une méthode -initWithCoder.

    - (id) initWithCoder:(NSCoder*)coder<br />{<br />	if(self = [super init])<br />	{<br />		[coder decodeValueOfObjCType:@encode(float) at:&amp;thickness];<br />		borderColor = [[coder decodeObject] retain];<br />	}<br />	<br />	return self;<br />	<br />}
    


    Flo, j'imagine bien qu'il y a une logique, mais je crois que tu t'y prends mal.
  • FloFlo Membre
    07:49 modifié #11
    Ben en fait mes données sont gérées sous forme d'arborescence et l'appDelegate est la racine. Je ne souhaite pas initialiser tout l'appDelegate via une archive mais juste ses noeuds fils.

    Je voudrai bien moi pouvoir l'initialiser avec initWithCoder mais le problème c'est qu'il est dur de se placer un niveau au dessus vu que l'appDelegate est initialisé dans un nib. J'ai essayé mais c'est tout crade.

    Au final la solution de shlum est pas si bizarre non ? (Charger tous les noeuds fils dans awakeFromNib ou applicationDidFinishLaunching:)
  • mpergandmpergand Membre
    07:49 modifié #12
    Ouais, mais c'est pas AppDelegate qu'il faut archiver, ce sont tes données.

    Crée un variable pour les contenir et le tour est joué.

    Je rejoins Céroce sur l'utilisation curieuse de AppDelegate, j'ai jamais de variable d'instance dans le AppDelagate, à  part des Outlets.

    Bon, j'en connais qui font bien des trucs du genre [NSApp delegate] maVariable  :) (sorry, private joke)
  • FloFlo Membre
    07:49 modifié #13

    j'ai jamais de variable d'instance dans le AppDelagate, à  part des Outlets.


    Ben ça dépends de ce qu'on veut faire non ? Si on prends un projet core data par exemple on a bien le managedObjectContext etc... en variables d'instance de l'AppDelegate...

    Bon je suis daccord, l'archiver c'est peut-être pas une bonne idée, mais je vais faire autrement du coup  ;)
  • mpergandmpergand Membre
    07:49 modifié #14
    dans 1231870183:


    j'ai jamais de variable d'instance dans le AppDelagate, à  part des Outlets.


    Ben ça dépends de ce qu'on veut faire non ? Si on prends un projet core data par exemple on a bien le managedObjectContext etc... en variables d'instance de l'AppDelegate...



    Exact, tu as raison 

    Perso, j'utilise pas coreData, ça doit être pour ça ...
Connectez-vous ou Inscrivez-vous pour répondre.