[Résolu] Chargement de fichier XML (PLIST) et plantage
wisky
Membre
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 :
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 :
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...
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:@"1"] objectForKey:@"CFG"] objectForKey:@"adress"];
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...
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
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 ?
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).
Par contre je ne connaissait pas objectForKeyPath. Je vais regarder...
Pour ce qui est du plantage. si je fait :
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
Une clée manquante retourne nil et ne fait pas planté l'appli
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.
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?:
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.
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
%
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.
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é
Il faut pas oublier :