{NSDecimalNumber integerValue}在iOS8中表现异常

时间:2014-09-06 22:52:34

标签: objective-c ios8 nsdecimalnumber

好的团队,这很奇怪。 [NSDecimalNumber integerValue]表现得很奇怪。

我坐在一个断点处,试图弄清楚为什么我的应用程序的某些部分在iOS8中被破坏了,而且我正在查看名为" timeSeconds"的变量。在Xcode变量视图中看起来像这样:

_timeSeconds    (NSDecimalNumber *) 344.514533996581994496

但是当我在调试器中查询它时,我看到了:

(lldb) p [self.timeSeconds doubleValue]
(double) $14 = 344.51453399658192
(lldb) p [self.timeSeconds intValue]
(int) $15 = 344
(lldb) p [self.timeSeconds integerValue]
(NSInteger) $16 = -5
(lldb) p (NSInteger)[self.timeSeconds intValue]
(NSInteger) $17 = 344

看到" -5"?在我提交雷达之前,你们中的任何一个人都能重现或解释它吗?

这是SSCCE:

NSDecimalNumber *n = [NSDecimalNumber decimalNumberWithString:@"344.514533996581994496"];
NSLog(@"%@", n); // 344.514533996581994496
NSLog(@"%ld", (long)[n intValue]); // 344
NSLog(@"%ld", (long)[n integerValue]); // -5
NSLog(@"%ld", (long)[n unsignedIntegerValue]); // 12

提前致谢!

马修

4 个答案:

答案 0 :(得分:14)

integerValue 的结果令人惊讶,但据我所知,记录在案:

NSDecimalNumber 继承自 NSNumber 。在 NSNumber 的子类注释中,声明了这一点 " ...子类必须覆盖与声明的类型对应的访问器方法 - 例如,如果objCType的实现返回“i”,则必须覆盖intValue ... &#34 ;

objCType 设置为内部指针,因此应与 NSNumber 相同。

NSDecimal 不会覆盖 intergerValue 。 它会覆盖 doubleValue ,因此应该可以正常工作。

唯一令我惊讶的是:它似乎没有覆盖 intValue ......

答案 1 :(得分:2)

真是个大错!我发现自己被它欺骗了。所以,只是结束doggods回答:

请勿:

NSInteger x = [myDecimalNumber integerValue];

相反,请执行此操作:

NSInteger x = (NSInteger)[myDecimalNumber doubleValue];

答案 2 :(得分:0)

使用myDecimalNumber.intValue代替integerValue

答案 3 :(得分:0)

你可以使用intValue或unsignedIntValue,但是 NOT integerValue或unsignedIntegerValue。这是一个演示该问题的单元测试,表明它与需要超过64位精度的数字有关:

func beginsWithVowel(x: String) -> Bool {
    let regex = try! NSRegularExpression(pattern: "^[aeiou]", options: .caseInsensitive)
    return regex.firstMatch(in: x, range: NSMakeRange(0, x.utf16.count)) != nil
}