[Résolu] Chargement de fichier XML (PLIST) et plantage

wiskywisky Membre
août 2008 modifié dans Vos applications #1
Bonjour a tous,


Je suis en cours d'écriture d'une application pour faire de l'électronique sur mac.
Dans mon cas, j'ai deux base de données que je doit charger. Les données sont stockées dans un fichier XML formaté comme une PLIST APPLE.

La Première base nommé Devices se charge bien et est fonctionnel.
La 2ième base nommé Memory se charge bien mais fait planté le programme lorsque que j'essaie d'y accéder.

Ses deux variables sont défini dans le fichier Header de l'objet tel que :
NSDictionary * devices;<br />NSDictionary * memory;


Dans mon fichier .m, je demande le chargement des fichiers dans l'init de l'objet. Là  tout va bien

Seulement après, quand on appel une fonction qui cherche un element dans memory tout plante :
NSString * data = [[[memory objectForkey:@&quot;1&quot;] objectForKey:@&quot;CFG&quot;] objectForKey:@&quot;adress&quot;];


J'ai vérifier si le fichier était bien formaté et c'est le cas. En fait cette ligne fonctionne à  la fin de la méthode de chargement de la DB ainsi que dans l'init de l'objet (après l'appel du chargement de la DB bien sur).

Je suis passé en mode débug pour voir si mon pointeur Memory n'était pas vidé après l'init. Ce n'est pas le cas.

Je ne sais absolument pas où est le bug !  :why?:

PS: Je n'ai pas mon projet sous la main je posterai les bonnes lignes de code plus tard...

Réponses

  • AliGatorAliGator Membre, Modérateur
    19:36 modifié #2
    Ahh en voyant [tt][Memory objectforkey:@1][/tt] je me suis dit "ben c'est facile il appelle "objectforkey" au lieu de "objectForKey" et en plus sur une classe (dès que je vois une variable qui commence par une majuscule, je me dit forcément que c'est une classe, par convention de nommage... ça pourrait être une idée de suivre les conventions Apple de ce côté m'enfin c'est qu'une question de lecture)...

    Mais en fait non puisque memory est bien un objet et qu'à  priori tu as tapé le code de mémoire et non copié/collé depuis ton projet donc j'imagine que dans le vrai tu as bien mis "objectForKey"... (d'ailleurs pourquoi ne pas utiliser [tt]objectForKeyPath:@1.CFG.address[/tt] ? Enfin bref)

    Ce qui est étonnant c'est que ça plante : si tu n'avais pas l'objet demandé dans ta hiérarchie, l'un de tes objectForKey te renverrai "nil", et envoyer ensuite un message (comme un autre objectForKey) à  nil n'a pas d'effet, donc data aurait valu nil, mais n'aurait pas planté ton programme...
    Mais bon ça vaut le coup de décomposer quand même ta ligne de code pour voir la tronche que ça a...
    Si tu fais un [tt]NSLog(@%@" , Memory)[/tt] (ou sur [Memory objectForKey:@1] par exemple) ça donne quoi ? ça plante ? ou pas ?
  • CéroceCéroce Membre, Modérateur
    19:36 modifié #3
    Il va falloir être plus précis, d'après ton appel [[[Memory objectforkey:@1] objectForKey:@CFG] objectForKey:@adress], tu as créé un arbre de 3 dicos, ce dont tu ne parles pas dans ta description.

    Commence par décomposer cet appel pour voir s'il y a bien trois objets renvoyés. M'est avis qu'il doit manquer une clef d'un des dicos (par exemple "adress" qui serait mieux orthographié "address").

    (Grillé par Ali).
  • wiskywisky Membre
    août 2008 modifié #4
    En effet dans mon projet, mes objets ne commence pas par une majuscule et c'est bien objectForKey: qui est écrit...
    Par contre je ne connaissait pas objectForKeyPath. Je vais regarder...

    Pour ce qui est du plantage. si je fait :
    NSLog(@&quot;Memory %@&quot;, memory);
    

    après le chargement du fichier, l'affichage est correcte et les données sont en place. Mais la même ligne dans une autre fonction fait planté.

    En général le code de fin d'exécution de retourné est le 11

    dans 1218546546:
    Commence par décomposer cet appel pour voir s'il y a bien trois objets renvoyés. M'est avis qu'il doit manquer une clef d'un des dicos (par exemple "adress" qui serait mieux orthographié "address").


    Une clée manquante retourne nil et ne fait pas planté l'appli ;)
  • NoNo Membre
    19:36 modifié #5
    Quelle est la ligne qui charge le plist ?

    Car si tu utilises une méthode convenient pour le chargement, et si tu oublies le retain qui va bien, ton NSDictionary sera très vite purgé de la mémoire, d'où les plantages ultérieurs quand tu tentes d'y accéder.
  • wiskywisky Membre
    19:36 modifié #6
    Non, le fichier est lue avec cette ligne :
    memory = [NSDictionary initWithContentOfFile:path];
    


    Le problème c'est que le pointeur est correcte il ne change pas d'adresse !!!
    De plus les deux fichiers son charger de le même façon. J'ai fait un copier coller du code pour charger le 2ieme fichier. J'ai changé les noms des variables (sauf les variable locale) et le nom de la fonction bien sur...


    :why?: :why?: :why?:
  • AliGatorAliGator Membre, Modérateur
    19:36 modifié #7
    dans 1218549390:

    Non, le fichier est lue avec cette ligne :
    memory = [NSDictionary initWithContentOfFile:path];
    

    Et le alloc alors ?
  • AliGatorAliGator Membre, Modérateur
    19:36 modifié #8
    dans 1218549390:

    De plus les deux fichiers son charger de le même façon. J'ai fait un copier coller du code pour charger le 2ieme fichier. J'ai changé les noms des variables (sauf les variable locale) et le nom de la fonction bien sur...
    Oh ça le copier/coller... il suffit d'avoir oublié de renommer une des variables juste à  un endroit bien caché... Genre avoir laissé le nom de l'ancienne variable quand tu envoies un "retain"... du coup ton tableau devices pourrait avoir 2 retains et ton memory aucun juste parce que tu as oublié de remplacer une occurence lors du copier/coller...
  • NoNo Membre
    19:36 modifié #9
    dans 1218549390:

    Non, le fichier est lue avec cette ligne :
    memory = [NSDictionary initWithContentOfFile:path];
    

    Le problème c'est que le pointeur est correcte il ne change pas d'adresse !!!
    De plus les deux fichiers son charger de le même façon. J'ai fait un copier coller du code pour charger le 2ieme fichier. J'ai changé les noms des variables (sauf les variable locale) et le nom de la fonction bien sur...


    Ce n'est pas parce que le pointeur ne change pas que c'est bien. Il suffit que les infos pointées par le pointeur changent, elles, pour faire planter ton appli. Or généralement, c'est le cas lors d'un objet qui est purgé, et dont la zone mémoire est à  nouveau employée par un autre objet.

    Mais, et Ceroce l'as écrit, sans plus de code, c'est difficile de pister l'origine de ton erreur.
  • Philippe49Philippe49 Membre
    août 2008 modifié #10
    dans 1218549390:

    Non, le fichier est lue avec cette ligne :
    memory = [NSDictionary initWithContentOfFile:path];
    

    Le problème c'est que le pointeur est correcte il ne change pas d'adresse !!!

    Je comprends mal cette phrase : " le pointeur est correct , il ne change pas d'adresse."

    On doit faire ainsi
    NSDictionary * memory;           
    memory = [[NSDictionary alloc] initWithContentsOfFile:path]; 

    [

    [size=12pt]Expérience :[/size]
    #import <Foundation/Foundation.h>

    int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];
    NSDictionary * memory;
    NSLog(@%p,memory);
    memory=[[NSDictionary  alloc] initWithContentsOfFile:@/Users/bureau/Library/Preferences/com.apple.ActivityMonitor.plist];
    NSLog(@%p,memory);
    [memory release];
    [pool drain];
    return 0;
    }

    % pgm
    2008-08-13 07:56:57.254 pgm[363:10b] 0x1000
    2008-08-13 07:56:57.256 pgm[363:10b] 0x106110
    %

    dans 1218550256:

    Ce n'est pas parce que le pointeur ne change pas que c'est bien. Il suffit que les infos pointées par le pointeur changent, elles, pour faire planter ton appli. Or généralement, c'est le cas lors d'un objet qui est purgé, et dont la zone mémoire est à  nouveau employée par un autre objet.

    Effectivement, si quelque part il y a un [memory release]; , l'adresse pointée par memory sera toujours la même, et la mémoire libérée aura pu être utilisée pour une allocation.

  • wiskywisky Membre
    août 2008 modifié #11
    C'est résolu.

    c'était bien l'initialisation qui faisait planté.

    Mais pourquoi pour l'autre DB ça marchais nickel et pour elle non ?





    En tout cas un grand merci à  vous tous !!!

    C'est ma tourné  :p :p :p :p :p :p :p :p
    Il faut pas oublier :  <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3
Connectez-vous ou Inscrivez-vous pour répondre.