【问题标题】:NSDictionary initWithContentsOfFile: messes up NSDecimalNumbers, why?NSDictionary initWithContentsOfFile:弄乱了 NSDecimalNumbers,为什么?
【发布时间】:2010-09-30 20:29:07
【问题描述】:

在我的 iPhone 应用程序中,我使用 NSDecimalNumber 来存储一些货币汇率值。 我在第一次启动应用程序时从网络上提取数据,然后在它们过时时再次提取数据,并将它们存储在 NSDictionary 中;然后我使用writeToFile:atomically:

第一次启动应用程序时,我的汇率转换方法可以正常工作。然而,当我第二次启动该应用程序时,费率以-(NSDictionary*) initWithContentsOfFile: 加载时,转换方法停止工作,我得到了奇怪的结果。

我在犯罪方法中使用断点进行了一些调试,发现费率数据被视为NSCFNumber,而不是NSDecimalNumber。因此,initWithContentsOfFile 似乎没有为我的对象分配正确的类。作为记录,这些对象的实际值,如description方法所示,对应于期望的速率值。

我还检查了writeToFile:atomically:生成的plist文件,发现rates存储为real;我想知道这是否是正确的类型。

知道发生了什么吗?

提前致谢,
大卫

【问题讨论】:

    标签: iphone objective-c cocoa cocoa-touch currency


    【解决方案1】:

    属性列表不区分十进制数和浮点数。 real 元素包含一个浮点数。 (实际上,序列化本身可能只是 NSNumber 向其自身发送 floatValue,而没有意识到该实例实际上是一个子类。这意味着当您生成 plist 数据,而不是当你读回它时。)

    我认为,您必须将其存储为字符串。希望这是无损的。

    【讨论】:

    • 我使用了使用字符串存储 NSDecimalNumbers 的方法,它似乎在保持精度方面做得很好。它似乎尽可能接近无损。
    【解决方案2】:

    Plists 仅适用于某些数据类型,而 NSNumber 就是其中之一。如果你想要 NSDecimalNumber 那么你有两种方法可以解决它。首先是继续使用 plist,然后在加载后将所有 NSNumbers 转换为 NSDecimalNumbers。二是改用 NSKeyedArchiver 来存储数据。这需要更多的代码,但意味着如果你保存一个 NSDecimalNumber,你会得到一个 NSDecimalNumber。

    【讨论】:

    • 请注意,如果属性列表序列化程序将数字视为 NSNumbers 并在 序列化时要求它们的 floatValue,那么到那时您已经失去了精度。获取这些信息为时已晚。
    • 好点子,我想我会听从 Peter 的建议并将值存储为 NSString。
    猜你喜欢
    • 1970-01-01
    • 2014-02-18
    • 2013-04-05
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多