将NSValue转换为NSDecimalNumber

时间:2009-07-07 03:36:14

标签: cocoa cocoa-touch

我有一个plist(在XCode中创建),其中包含一个充满“Numbers”(0.01,1,2,6)的数组,当使用initWithContentsOfFile重构时,它会解压缩到NSValues中。如何将这些NSValues转换为可以用于一起添加的NSDecimalNumbers?它们将被视为货币值,因此只需要精确到2(可能是4)小数位。

我尝试将plist值保存为“String”而不是“Number”,并使用NSDecimalNumber的initWithString设置值,但NSValue不响应stringValue。

似乎处理数字在Cocoa中尤其令人困惑。在如此多的框架中有如此多的容器格式...: - (

2 个答案:

答案 0 :(得分:1)

您应该能够将数字直接存储在属性列表中作为字符串。在将它们存储在plist中时,您不需要为NSStrings执行任何NSValue包装。我建议将应用程序中的数字保存为NSDecimals或NSDecimalNumbers以避免任何浮点错误,使用initWithString:locale:从plist中读取它们,并使用descriptionWithLocale将它们写入plist:将小数存储和检索为字符串可以避免任何来回浮点转换错误。

答案 1 :(得分:0)

要学习的第一课是,在表示货币时,如果您想要任何精确度,请使用整数而不是浮点(十进制)数字。 (每当你需要显示分数时除以100.0等)计算机是完美无缺的二进制(基数2)但是如果你试图用二进制表示不能分解成1/(2^n)因子的东西,那你就是'我会遇到精确错误。 (尝试0.1 + 0.1,看看你得到了什么。)

也就是说,当你使用类似-[NSArray initWithContentsOfFile:]之类的东西来“重构”它时,你在其中指定数字的XML标记肯定会对用Cocoa类解释值的方式产生影响。有关详细信息和示例,请参阅plist man pagethis Apple article

要完成您的要求,请确保您在plist中的值周围使用<real><integer>(以及匹配的结束标记)。 (属性列表编辑器和Xcode应根据数字是否有小数点自动使用正确的。)在我的测试中,实数和整数都作为NSNumber对象读入。 NSDecimalNumber是NSNumber的子类,但我不完全确定CFNumber的免费桥接如何在所有情况下都能正常工作。实验可能是解决问题的最好方法。