NSUserDefaults sur le simulateur
guittonews
Membre
Bonjour à tous
J'avance de mieux en mieux et me retrouve confronter à de moins en moins de problème (même si comme tout débutant je pense que la qualité de mon code en prend un coup...les reflexions philosophiques lié au code viendront avec l'experience ).
Il n'empêche que je suis confronter à un problème avec les NSUserDefaults :
Je lance mon appli, je me log, je sauvegarde mes infos no problemo.
Je ferme l'appli (pas le simulateur!) je réouvre et la plsu rien....C'est grave docteur?
Je mettrai plus d'info si jamais ce n'est pas le comportement normal du simulateur
Merci à vous tous
J'avance de mieux en mieux et me retrouve confronter à de moins en moins de problème (même si comme tout débutant je pense que la qualité de mon code en prend un coup...les reflexions philosophiques lié au code viendront avec l'experience ).
Il n'empêche que je suis confronter à un problème avec les NSUserDefaults :
Je lance mon appli, je me log, je sauvegarde mes infos no problemo.
Je ferme l'appli (pas le simulateur!) je réouvre et la plsu rien....C'est grave docteur?
Je mettrai plus d'info si jamais ce n'est pas le comportement normal du simulateur
Merci à vous tous
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Juste une idée comme ça.
Eric
J'ai du coup regardé un peu plus en profondeur les exemple de la doc (drilldown et apppreferences) et je n'ai pas bien vu ce que je faisais de différent...
du coup je vous montre ce que j'ai fait :
A un moment donné j'enregistre des informations relatives au login
A "l'autre bout" de mon application je met une trace (pas dans la console parce que au "re lancage" de l'appli elle n'apparait plus) :
Quand je me log, je vais voir ma trace ca marche nikel (ca m'affiche l'id). Je quitte l'appli (sans fermer le simulateur) et la relance. vais voir ma trace et la plus rien
Why?
Merci
NSLog(@%@",[standardUserDefaults dictionaryRepresentation]);
Autrement un petit essai qui marche (un view controller avec deux UITextField, le contenu du textField 1 est enregistré dans les defaults, et reporté à l'ouverture dans le textField 2) :
- Supprimer le Build
- Supprimer l'appli dans le simulateur
- et des fois que, Build > Clean All Targets
Bon je crois que je vais me replonger dans la doc parce que je ne vois pas trop ce que je fais de différent par rapport à toi non plus...La seul diff viendrait du coté de ta méthode initialize...Mais je ne vois pas avec quoi initialiser mon truc...
Je vais essayer d'expliquer ce que j'ai compris, vous me reprenez si je me trompe.
//set
Je créé un Mutable.
Je le rempli.
Je le set dans UserDefaults avec une key.
Je synchronise.
//get (dans la meme session)
Je chope mes UserDefaults
Je get mon objet avec la key.
/*pour moi ca marche jusque là */
//get (dans une autre session)
Je chope mes UserDefaults
Je get mon objet avec la key
/*là ça chie*/
Dans les différents exemples que j'ai pu voir (doc/philippe49), il y a une phase "d'initialisation" des UserDefaults au lancement de l'appli. Est elle obligatoire?
Thx a lot.
Ptite question hors sujet : on peut voir les log meme pour un "relançage" de l'appli?
Je pose la question, parce que j'aurais plutôt tendance à utiliser un int pour stocker un id, et le convertir en NSNumber au dernier moment.
Non
Dans la console (Application/Utilitaires) , system.log
Avec un NSInteger , on utilise setInteger: forKey:
C'est donc que tu réécris dans ce fichier ...
- En cours de fonctionnement de ton appli ?
- Dans applicationWillTerminate: ?
Dans [loginValues setObject:idUtilisateur forKey:@idInscrit]; idUtilisateur ne peut pas être un int.
Il faudrait mettre [loginValues setObject:[NSNumber numberWithInt:idUtilisateur] forKey:@idInscrit];
Merci je regarde ca
A priori c'est le seul endroit dans mon code ou JE touche aux userdefaults (je viens de mettre un log dans applicationWillTerminate et j'ai toujours mes données...)
Par rapport à ce que dit Ceroce, en effet en terme d'optimisation je devrais le faire. Cepandant un Int est aussi un objet donc en brut je devrais récup mon objet (quel qu'il soit) dans ma nouvelle session...
Ah pas du tout, un objet c'est un pointeur. C'est fondamental d'encapsuler l'int dans un objet pour pouvoir le stocker dans un dictionnaire.
Je pensais que Int ou String héritaient de Object donc que à partir de ce constat là je pouvais les stoquer en objet et qu'il n'y avait pas de problèmes (et ca marchait dans la même session donc...). Tout en étant d'accord que c'est crade!! Mais bon XP...coder crade mais rapidement puis faire du refactoring
Je fais ces modifs là entre midi et deux et vous tiens au courant. Merci
Il faut que ce soit des NSString *
Je suis en train de tracer encore plus ce queje fais pour essayer de voir à quel moment ca chie vraiment....
Je log mes UserDefaults dans mon applicationWillterminate : resultat j'ai mes données à ce moment là .
Je réouvre l'appli : je trace dans applicationDidFinishLaunching: plus rien....
Après un "synchronize", vérifie aussi que le plist des préférences est créé dans ce dossier, et si oui regarde ce qu'il contient, voir s'il est vide ou s'il a tes informations, pour savoir si c'est l'enregistrement sur disque qui débloque, ou la lecture depuis le disque...
Edit : je n'ai pas le dossier iPhone simulator dans application support
Je pense que je n'utilisé pas la bonne méthode pour sauvegarder dans mes UserDefaults, après savoir pourquoi cela marchait dans la "même" session mais non persistent...i don't know.
voilà ce que je faisait :
et voila ce que je fais (je rempalce la ligne du dessus par celle ci) :
Ce qu'il y a un peu au dessus dans le code se trouve en premeire page du fil de discussion (pour les curieux )
Je suis désolé de vous avoir fait perdre du temps et vous remerci
a (très) bientôt !!
Pas étonnant.
C'est on-ne-peut-plus-explicite dans la doc : la méthode registerDefaults: ajoute le dictionnaire passé en paramètre aux userDefaults de l'appli, mais en mémoire. Donc, il n'y a pas d'écriture sur le disque.
Cela sert par exemple à "concaténer" le contenu d'un plist quelconque avec les véritables userDefaults lus depauis le disque.
Petite quesiton au passage : disons que je stock un mutabledictionary.
Hop setObject: forkey: bim bam tout va bien, j'enchaine je veux récup mon mutabledictionary pour le modifier et la patatrak.
Puis-je récuperer un mutableDictionary de mon UserDefault?
Pas la peine de me sortir un RTFM , j'ai bien vu ça :
Merciiiii
NSDictionary* dict = [[NSUserDefaults ...] ...];
NSMutableDictionary* mdict = [dict mutableCopy];
[dict release];
// do sthg with mdict
Merci merci merci :(renaud):
Voilà , je bute contre un mur ( :crackboom:- ) et malgré quelque dizaine de passage en mode débug, et un tracage exhaustif dans la console je ne vois toujours pas....
D'abord le code j'explique ensuite ce que je fais (ou ai voulu faire...)
J'ai un dictionary dans mes usersdefaults, qui contient d'autre dictionary (en gros mon arborescence). Puis j'arrive sur une vue qui me permet de mettre à jour le dernier niveau de l'arborescence (ici codé en dur au niveau de : "set du texte dans visage").
Le log que j'ai laissé ici m'affiche bien mon dictionary au complet avec ma modif. Cependant j'ai un exec bad acces sur ma derniere ligne (pour virer le boutton "done").
Là où c'est louche c'est que si je vire tout mon code qui traite avec les usersdefaults ca passe nikel o_0
Une piste? un conseil? Je suis preneur
Merci à tous et bon début de semaine
[tt]
- (void)saveAction:(id)sender
{
  //
recup speedsmos
  NSDictionary *pref= [[NSUserDefaults standardUserDefaults] objectForKey:@speedsmos];
  NSMutableDictionary* speedsmos = [pref mutableCopy];
  [pref release];
  //[speedsmos setObject:visageDefault forKey:@Visage];
  //
recup visage
  NSDictionary *pref1= [speedsmos objectForKey:@Visage];
  NSMutableDictionary* visage = [pref1 mutableCopy];
  [pref1 release];
  //
set du texte dans visage
  [visage setObject:textViewD.text forKey:@Cheveux];
  //
set du visage dans speedsmos
  [speedsmos setObject:visage forKey:@Visage];
  //
set de speedsmos dans userdefaults
  [[NSUserDefaults standardUserDefaults] setObject:speedsmos  forKey:@speedsmos];
  [speedsmos release];
  [[NSUserDefaults standardUserDefaults] synchronize];
  NSLog(@%@",[[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);
  [textViewD resignFirstResponder];
  self.navigationItem.rightBarButtonItem = nil;
}
[/tt]
Un rappel sur les release : on ne doit faire un release sur un objet que si on l'a précédemment créé dans son code (donc issu d'un alloc/init, d'un new ou d'un copy).
pref et pref1 sont des objets en autorelease (car non créés par aucune des méthodes précédentes).
Ils vont donc recevoir un release implicite un peu plus tard (lors du vidage de l'autorelease pool, généralement).
Si toi tu fais aussi un release, alors le premier va détruire effectivement l'objet, et le second va tenter de détruire un objet qui n'existe plus, donc PLANTAGE.
'tin que ferais - je sans vous tous!!!
tournée généraaaleeeeeee :