NSDictionary initWithContentsOfFile:NSDecimalNumbersを台無しにしたのはなぜですか?
-
10-07-2019 - |
質問
iPhoneアプリでは、 NSDecimalNumber
を使用して、いくつかの通貨レート値を保存します。
アプリを最初に起動したときにWebからデータを取得し、それらが古くなったときに再度取得し、 NSDictionary
に保存します。次に、 writeToFile:atomically:
を使用します。
アプリを初めて起動すると、レート変換方法は問題なく機能します。それでも、アプリをもう一度起動すると、レートが-(NSDictionary *)initWithContentsOfFile:
でロードされると、変換方法が機能しなくなり、奇妙な結果が得られます。
問題のあるメソッドでブレークポイントを使用してデバッグを行いましたが、レートデータが NSDecimalNumber
ではなく NSCFNumber
として表示されることがわかりました。したがって、 initWithContentsOfFile
がオブジェクトに適切なクラスを割り当てていないようです。レコードの場合、これらのオブジェクトの実際の値は、 description
メソッドに示されているように、期待されるレート値に対応しています。
writeToFile:atomically:
によって生成されたplistファイルも確認し、レートが real
として保存されていることを確認しました。これが正しいタイプかどうか疑問に思います。
何が起こっているのか?
ありがとうございます、
ダビデ
解決
プロパティリストは、10進数と浮動小数点数を区別しません。 real
要素は、浮動小数点数を保持します。 (実際には、シリアル化自体は単に NSNumber
が floatValue
を自分自身に送信するだけで、インスタンスが実際にサブクラスのものであることを意識することはありません。 plistデータを読み直すときではなく、生成します。)
文字列として保存する必要があると思います。うまくいけば、それはロスレスです。
他のヒント
Plistは特定のデータ型でのみ機能し、NSNumberはその1つです。 NSDecimalNumberが必要な場合は、2つの方法があります。 1つ目は、plistを使い続け、ロード後にすべてのNSNumberをNSDecimalNumbersに変換することです。 2つ目は、NSKeyedArchiverを使用してデータを保存することです。これにはより多くのコードが必要ですが、NSDecimalNumberを保存するとNSDecimalNumberが返されます。