2009-07-23 20 views
0

Ich könnte Hilfe gebrauchen. Nach ein paar frustrierenden Tagen mit Versuch und Irrtum bekomme ich inkonsistente Ergebnisse beim Schreiben von Einstellungen in NSUserDefaults.iPhone SDK NSUserDefaults speichert keine korrekten Werte

Hier sind die aufeinander folgenden Codezeilen:

 NSLog(@"startTimer(): End Time defaults: %f\n", [defaults floatForKey:kEndTimeKey]); 
    NSLog(@"startTimer(): new End Time: %f\n", endTime); 
    [defaults setFloat:endTime forKey:kEndTimeKey]; 
    [defaults synchronize]; 
    NSLog(@"startTimer(): stored EndTimeKey: %f\n", [defaults floatForKey:kEndTimeKey]); 

kEndTimeKey ein konstanter String ist.

Wie Sie sehen können, protokolliere ich den aktuellen Wert für den Schlüssel, dann logge ich den Wert, den ich speichern möchte, synchronisieren und lese den gespeicherten Wert erneut. Scheint mir einfach, aber hier ist der Ausgang Debugger:

2009-07-22 22:05:43.263 TimerTest3[1584:207] startTimer(): End Time defaults: 0.000000 
2009-07-22 22:05:43.266 TimerTest3[1584:207] startTimer(): new End Time: 270018630.916571 
2009-07-22 22:05:43.287 TimerTest3[1584:207] startTimer(): stored EndTimeKey: 270018624.000000 

Ich sehe den ursprünglichen Wert 0, den Wert bestimmt in 571 endet, und der Wert aus dem Cache gelesen, die aus 6 Sekunden ist.

Ich bin mir nicht sicher, woher der neue Standard kam. Irgendwelche Ideen? Ich bekomme ähnliches Verhalten am Gerät und am Simulator.

Dank Brad

Antwort

1

Wie setzen Sie endTime. Ist es ein Double? Ich bin relativ sicher, dass dies kein NSUserDefaults-Problem ist, sondern ein Gleitkomma-mathematisches Problem.

270018630.916571 ist 16 Dezimalziffern, die ~ 48 Bits Daten übernimmt, um die Mantisse zu speichern. Ein Fließkommawert ist 32 Bits, aber ein Bit davon ist ein Vorzeichenbit, 8 Bits des Exponenten und 23 Bits der Mantisse. Das bedeutet, dass der Wert, den Sie sehen, viel größer ist, als ein Float halten kann, und ein gewisser Verlust an Genauigkeit wird erwartet. Selbst wenn Sie es auf 270018630 ​​kürzen, dauert es immer noch ~ 28 Bits percision auszudrücken, was bedeutet, dass es in Inkrementen gerundet werden muss, die größer als eine ganze Zahl sind.

Fließkommazahlen lassen Sie nicht magisch größere Zahlen als Ints mit der gleichen Anzahl von Bits ausdrücken. Sie schaffen die Fähigkeit, große Zahlen zu speichern, indem sie die Lücke zwischen Zahlen verändern und Metadaten (den Exponenten) verwenden, um sie zu verfolgen. Wikipedia hat eine anständige explanation davon, wie sie arbeiten.

+0

Ich glaube, dass Sie richtig sind. Ich habe versucht, NSTimeIntervals zu speichern, die als Doppel definiert sind. Das erklärt, warum Funktionalität in einigen Fällen eng war, in anderen inkonsistent und für kleine Zahlen in Ordnung. –