comportement par défaut incohérent (NSUserDefaults) dans les paramètres par défaut du simulateur iPhone

StackOverflow https://stackoverflow.com/questions/475367

  •  19-08-2019
  •  | 
  •  

Question

J'ai constaté des résultats très contradictoires lors du développement d'une application iPhone et de la sauvegarde des préférences via le mécanisme NSUserDefaults standard. J'utilise du code presque tout droit sorti du livre de cuisine du développeur pour iPhone d'Erica Sadun (livre fantastique), il se présente comme suit:

(void) updateDefaults
{
    NSMutableArray *spells =  [[NSMutableArray alloc] init];
    NSMutableArray *locs = [[NSMutableArray alloc] init];

    for (DragView *dv in [boardView subviews]) 
    {
        [spells addObject:[dv whichSpell]];
        [locs addObject:NSStringFromCGRect([dv frame])]; 
    }

    [[NSUserDefaults standardUserDefaults] setObject:spells forKey:@"spells"];
    [[NSUserDefaults standardUserDefaults] setObject:locs forKey:@"locs"];
    [[NSUserDefaults standardUserDefaults] synchronize];

    [spells release];
    [locs release];
}

Les valeurs sont enregistrées, parfois ... et restaurées, parfois. Je ne peux pas obtenir une perle exacte sur ce qui le fait ou ne le fait pas fonctionner.

Quelqu'un d'autre a-t-il vécu des expériences similaires? Des suggestions sur ce qui pourrait le faire fonctionner? La méthode de synchronisation est-elle le meilleur moyen de forcer une écriture sur le disque et de sauvegarder les valeurs, ou existe-t-il quelque chose de mieux (tant pour la production que pour le simulateur).

Merci Ryan

Était-ce utile?

La solution

Vous devriez utiliser un NSKeyedArchiver pour enregistrer vos tableaux, tel que:

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:spells] forKey:@"spells"];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:locs] forKey:@"locs"];
[[NSUserDefaults standardUserDefaults] synchronize];

Assurez-vous également que votre classe spells implémente le protocole NSCoding (encodeWithCoder: et initWithCoder :), s'il s'agit d'une classe personnalisée. Il semble que vos locs soient NSStrings, qui archiveront parfaitement.

Vous devrez également faire quelque chose comme

NSData *dataRepresentingSavedSpells = [currentDefaults objectForKey:@"spells"];
if (dataRepresentingSavedSpells != nil)
{
    NSArray *oldSpells = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedSpells];
}

Pour charger les anciennes valeurs à partir des valeurs par défaut.

J'utilise synchronize pour écrire sur le disque à la sortie, et l'expérience a été très fiable.

Autres conseils

Sous Mac OS X, et probablement aussi sous iPhone OS, la base de données par défaut ne peut contenir que des objets de liste de propriétés: NSString, NSNumber, NSArray, NSDictionary et NSData.

L'extrait de code n'indique pas le type d'un sort, mais s'il ne correspond à aucun des éléments ci-dessus, il ne sera pas stocké dans la base de données par défaut. Vos options sont:

  1. Ecrivez une méthode qui convertira votre objet en une représentation de plist. En d'autres termes, une méthode pour créer un NSDictionary à partir de votre objet et une autre méthode pour l'initialiser à l'aide d'un NSDictionary. Vous pouvez également choisir de le stocker en tant que NSArray ou NSString.
  2. Assurez-vous que votre objet implémente le protocole NSCoding, puis utilise NSKeyedArchiver pour convertir l'objet en objet NSData et NSKeyedUnarchiver pour le reconvertir.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top