Comportamiento de valores predeterminados inconsistentes (NSUserDefaults) en los valores predeterminados del simulador de iPhone

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

  •  19-08-2019
  •  | 
  •  

Pregunta

He estado experimentando resultados muy inconsistentes mientras desarrollaba una aplicación para iPhone e intentaba guardar preferencias a través del mecanismo estándar NSUserDefaults. Estoy usando el código casi directamente del Libro de cocina para desarrolladores de iPhone de Erica Sadun (fantástico libro por cierto), se ve así:

(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];
}

Los valores se guardan, a veces ... y se restauran, a veces. No puedo obtener una cuenta exacta de lo que hace o no funciona.

¿Alguien más tiene alguna experiencia similar? ¿Alguna sugerencia sobre lo que podría hacer que funcione? ¿Es el método de sincronización la mejor manera de forzar una escritura de disco y hacer que los valores se guarden, o hay algo mejor (tanto para producción como para simulador)?

Gracias Ryan

¿Fue útil?

Solución

Debería usar un NSKeyedArchiver para guardar sus matrices, como por ejemplo:

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

También debe asegurarse de que su clase de hechizos implemente el protocolo NSCoding (encodeWithCoder: e initWithCoder :), si es una clase personalizada. Parece que sus locomotoras son NSStrings, que se archivarán perfectamente.

También deberás hacer algo como

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

Para cargar los valores antiguos de los valores predeterminados.

Utilizo sincronizar para escribir en el disco al salir, y ha sido muy confiable en mi experiencia.

Otros consejos

En Mac OS X, y probablemente también en iPhone OS, la base de datos predeterminada solo puede contener objetos de lista de propiedades: NSString, NSNumber, NSArray, NSDictionary y NSData.

De su fragmento de código no está claro qué tipo de hechizo es, pero si no es uno de los anteriores, no se almacenará en la base de datos predeterminada. Sus opciones son:

  1. Escriba un método que convierta su objeto ay desde una representación plist. En otras palabras, un método para crear un NSDictionary a partir de su objeto y otro método para inicializar el objeto usando un NSDictionary. También puede optar por almacenarlo como NSArray o NSString.
  2. Haga que su objeto implemente el protocolo NSCoding y luego use NSKeyedArchiver para convertir el objeto en un objeto NSData, y NSKeyedUnarchiver para convertirlo nuevamente.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top